日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

用mtrace定位内存泄漏

發(fā)布時(shí)間:2023/12/20 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用mtrace定位内存泄漏 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一. 緣起

有的公眾號(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的用途:

ubuntu@VM-0-15-ubuntu:~$ man mtrace MTRACE(1) Linux user manual MTRACE(1)NAMEmtrace - interpret the malloc trace logSYNOPSISmtrace [option]... [binary] mtracedataDESCRIPTIONmtrace is a Perl script used to interpret and provide human readable output of the trace log contained inthe file mtracedata, whose contents were produced by mtrace(3). If binary is provided, the output ofmtrace also contains the source file name with line number information for problem locations (assumingthat binary was compiled with debugging information).For?more?information?about?the?mtrace(3)?function?and?mtrace?script?usage,?see?mtrace(3).

顯然,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ì)如下:

ubuntu@VM-0-15-ubuntu:~$ man 3 mtrace MTRACE(3) Linux Programmer's Manual MTRACE(3)NAMEmtrace, muntrace - malloc tracingSYNOPSIS#include <mcheck.h>void mtrace(void);void muntrace(void);DESCRIPTIONThe mtrace() function installs hook functions for the memory-allocation functions (malloc(3), realloc(3)memalign(3), free(3)). These hook functions record tracing information about memory allocation and deal[mlocation. The tracing information can be used to discover memory leaks and attempts to free nonallocatedmemory in a program.The muntrace() function disables the hook functions installed by mtrace(), so that tracing information isno longer recorded for the memory-allocation functions. If no hook functions were successfully installedby mtrace(), muntrace() does nothing.When mtrace() is called, it checks the value of the environment variable MALLOC_TRACE, which should con[mtain the pathname of a file in which the tracing information is to be recorded. If the pathname is suc[mcessfully opened, it is truncated to zero length.If MALLOC_TRACE is not set, or the pathname it specifies is invalid or not writable, then no hook func[mtions are installed, and mtrace() has no effect. In set-user-ID and set-group-ID programs, MALLOC_TRACEis ignored, and mtrace() has no effect.

顯然,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)存泄漏的程序:

#include <stdio.h>int main() {setenv("MALLOC_TRACE",?"test.log",?"1");mtrace();int *p = (int *)malloc(2 * sizeof(int));return 0; }

我們來(lái)分析一下這段程序:

  • setenv是設(shè)置相關(guān)環(huán)境變量。

  • mtrace函數(shù)記錄malloc的trace log.

  • malloc函數(shù)用于分配堆內(nèi)存

我們來(lái)編譯并運(yùn)行一下(注意在編譯時(shí)帶-g參數(shù)):

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:~$ ls test.log test.log ubuntu@VM-0-15-ubuntu:~$ cat test.log = Start @ ./a.out:[0x4005eb] + 0x1649570 0x8 @ /lib/x86_64-linux-gnu/libc.so.6:(clearenv+0x5d)[0x7f1bc48f7e9d] - 0x1649010 @ /lib/x86_64-linux-gnu/libc.so.6:(tdestroy+0x4cf)[0x7f1bc49c291f] - 0x16490e0 @ /lib/x86_64-linux-gnu/libc.so.6:[0x7f1bc4a3223c] - 0x1649100

顯然,編譯運(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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。