用mtrace定位内存泄漏
一. 緣起
有的公眾號(hào)讀者,看完我上次寫(xiě)給大學(xué)生的查bug方法后,希望我多分享一些查bug的實(shí)踐經(jīng)驗(yàn)和具體步驟,比如如何查內(nèi)存泄漏和core dump問(wèn)題。所以,就打算寫(xiě)這篇文章。
二. 內(nèi)存泄漏簡(jiǎn)介
內(nèi)存泄漏,是一個(gè)談虎色變的問(wèn)題。我個(gè)人的基礎(chǔ)非常差,大學(xué)畢業(yè)后,才第一次聽(tīng)說(shuō)內(nèi)存泄漏。當(dāng)時(shí),我有點(diǎn)懵圈,心想內(nèi)存泄漏了,是要重新去買(mǎi)新的內(nèi)存設(shè)備嗎?很傻很天真!
后來(lái),我又聽(tīng)說(shuō)了很多次內(nèi)存泄漏,查資料后才知道,原來(lái)這是一個(gè)軟件層面的東西。比如,使用了malloc, 但沒(méi)有使用free, 或者使用了new, 但沒(méi)有使用delete, 都會(huì)造成內(nèi)存泄漏。
為什么說(shuō)內(nèi)存泄漏會(huì)談虎色變呢?因?yàn)?#xff1a;
內(nèi)存泄漏危害性大
內(nèi)存泄漏潛伏時(shí)間長(zhǎng)
內(nèi)存泄漏不容易定位
那么,如果內(nèi)存泄漏了,我們?cè)撊绾稳ザㄎ荒?#xff1f;在C/C++相關(guān)的面試中,不問(wèn)這個(gè)問(wèn)題的面試官,是不合格的;不會(huì)回答這個(gè)問(wèn)題的面試者,也是不合格的。當(dāng)然,這種說(shuō)法,似乎有一點(diǎn)絕對(duì)。
有的面試者回答,只有小心配對(duì)使用malloc/free和new/delete, 就能避免內(nèi)存泄漏。顯然,這種面試者缺乏基本的工程實(shí)踐認(rèn)知,缺乏對(duì)敵人的敬畏。
有的面試者回答,使用智能指針,就能避免內(nèi)存泄漏。顯然,這只是一種預(yù)防機(jī)制。在實(shí)際項(xiàng)目中,各種復(fù)雜因素導(dǎo)致的后果是內(nèi)存已經(jīng)泄漏,需要定位。
還有的面試者,更是想出了出人意料的答案,那就是檢查代碼!這又是對(duì)敵人缺乏了解啊。大型工程的代碼動(dòng)輒幾十萬(wàn)行,誰(shuí)敢走讀代碼來(lái)查內(nèi)存泄漏呢?
對(duì)我而言,查殺bug是我的相對(duì)強(qiáng)項(xiàng)(實(shí)話說(shuō),架構(gòu)能力需要加強(qiáng))。mtrace和valgrind是典型的內(nèi)存泄漏分析工具。今天,我們聊mtrace定位內(nèi)存泄漏。
三. mtrace簡(jiǎn)介
我們來(lái)看下mtrace的用途:
顯然,mtrace命令是用來(lái)分析malloc函數(shù)的trace log.?
那么,這個(gè)trace log是怎么生成的呢??且看上面的see mtrace(3). 有的朋友看到這里,不知道怎么敲命令了,以為是:
ubuntu@VM-0-15-ubuntu:~$ man mtrace(3) -bash: syntax error near unexpected token `(' ubuntu@VM-0-15-ubuntu:~$其實(shí),正確的姿勢(shì)如下:
顯然,mtrace函數(shù)是用來(lái)記錄malloc的trace log的。
所以,對(duì)于mtrace, 我們有如下的基本認(rèn)知:
mtrace函數(shù)記錄malloc的trace log
mtrace命令分析上述記錄的trace log
這也就是用mtrace來(lái)定位內(nèi)存泄漏的原理。那么,具體如何來(lái)查內(nèi)存泄漏呢?不要著急,繼續(xù)往下看。
四. 用mtrace定位內(nèi)存泄漏
首先,我們來(lái)寫(xiě)一段有內(nèi)存泄漏的程序:
我們來(lái)分析一下這段程序:
setenv是設(shè)置相關(guān)環(huán)境變量。
mtrace函數(shù)記錄malloc的trace log.
malloc函數(shù)用于分配堆內(nèi)存
我們來(lái)編譯并運(yùn)行一下(注意在編譯時(shí)帶-g參數(shù)):
顯然,編譯運(yùn)行后,生成了trace log, 即test.log文件。用cat命令查看,貌似也發(fā)現(xiàn)不了什么東西,這是因?yàn)?#xff0c;姿勢(shì)錯(cuò)了。
我們不僅僅要用test.log, 還要結(jié)合二進(jìn)制文件a.out呢,如下:
ubuntu@VM-0-15-ubuntu:~$ mtrace a.out test.log - 0x00000000018ab010 Free 3 was never alloc'd 0x7fb41725fe9d - 0x00000000018ab0e0 Free 4 was never alloc'd 0x7fb41732a91f - 0x00000000018ab100 Free 5 was never alloc'd 0x7fb41739a23cMemory not freed: -----------------Address Size Caller 0x00000000018ab570??????0x8??at?/home/ubuntu/test.c:8 ubuntu@VM-0-15-ubuntu:~$Oh, nice啊!終于查出是第8行,存在內(nèi)存泄漏。接下來(lái),我們打算修復(fù)代碼,并再次驗(yàn)證。
五. 修復(fù)后再驗(yàn)證
修復(fù)內(nèi)存泄漏后,代碼為:
#include <stdio.h>int main() {setenv("MALLOC_TRACE",?"test.log",?"1");mtrace();int *p = (int *)malloc(2 * sizeof(int));free(p);return 0; }編譯運(yùn)行,并查看是否有內(nèi)存泄漏:
ubuntu@VM-0-15-ubuntu:~$ gcc -g test.c ubuntu@VM-0-15-ubuntu:~$ ubuntu@VM-0-15-ubuntu:~$ ubuntu@VM-0-15-ubuntu:~$ ./a.out ubuntu@VM-0-15-ubuntu:~$ mtrace a.out test.log - 0x00000000006ad010 Free 4 was never alloc'd 0x7faa9b044e9d - 0x00000000006ad0e0 Free 5 was never alloc'd 0x7faa9b10f91f - 0x00000000006ad100 Free 6 was never alloc'd 0x7faa9b17f23c No memory leaks. ubuntu@VM-0-15-ubuntu:~$看到No memory leaks后,心情就好了,沒(méi)有內(nèi)存泄漏了。
六. 最后的話
無(wú)論是筆試面試,還是平時(shí)工作,對(duì)于內(nèi)存泄漏問(wèn)題,都要有自己的一套處理辦法。
推薦閱讀:
專輯|Linux文章匯總
專輯|程序人生
專輯|C語(yǔ)言
我的知識(shí)小密圈
關(guān)注公眾號(hào),后臺(tái)回復(fù)「1024」獲取學(xué)習(xí)資料網(wǎng)盤(pán)鏈接。
歡迎點(diǎn)贊,關(guān)注,轉(zhuǎn)發(fā),在看,您的每一次鼓勵(lì),我都將銘記于心~
總結(jié)
以上是生活随笔為你收集整理的用mtrace定位内存泄漏的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: HiJson修改版,修改为按json字符
- 下一篇: 使用xsd文件验证xml