Linux下關(guān)于mtrace工具排查內(nèi)存泄露的問題
mtrace工具排查內(nèi)存泄露
內(nèi)存泄露:為申請(qǐng)了堆內(nèi)存,但沒有釋放,即未還給操作系統(tǒng)。長(zhǎng)此以往,系統(tǒng)的可分配內(nèi)存越來越少,造成系統(tǒng)內(nèi)存的浪費(fèi),導(dǎo)致程序運(yùn)行速度減慢甚至系統(tǒng)崩潰等嚴(yán)重后果。
在 Linux下進(jìn)行 C/C++ 開發(fā),常常會(huì)動(dòng)態(tài)分配一些堆內(nèi)存。那就可能會(huì)存在"內(nèi)存泄露"的問題。
如果 Linux下做 C/C++ 開發(fā)時(shí),出現(xiàn)內(nèi)存泄漏了,我們?cè)撊绾稳ザㄎ荒兀?/p>
常用的定位工具:
mtrace 工具 與 valgrind工具 ,這兩個(gè)都是典型的內(nèi)存泄漏分析工具。
1. mtrace 工具使用思路
在我們的調(diào)用內(nèi)存分配和釋放的函數(shù)中裝載 “鉤子(hook)” 函數(shù),通過 “鉤子” 函數(shù)打印的 log 日志,對(duì)日志文件的分析來幫助我們分析對(duì)內(nèi)存的使用是否存在問題。
對(duì)該工具的使用包括兩部分內(nèi)容:一個(gè)是要修改源碼,裝載 hook 函數(shù)。
另一個(gè)是通過運(yùn)行修改后的程序,生成特殊的 log 文件。
然后利用 mtrace工具分析日志,判斷是否存在內(nèi)存泄露以及定位可能發(fā)生內(nèi)存泄露的代碼位置。
2. mtrace 工具使用說明
接下來用一段代碼說明一下, mtrace 工具如何定位 "內(nèi)存泄露" 。
在使用之前,需要修改我們的源碼,用來跟蹤內(nèi)存分配和釋放,其中需要使用兩個(gè)函數(shù):
#include <mcheck.h> void mtrace(void); //開啟內(nèi)存分配跟蹤 void muntrace(void); //關(guān)閉內(nèi)存分配跟蹤
將上述函數(shù)接口加入待檢測(cè)的代碼中,代碼如下:
#include <stdlib.h> #include <stdio.h> #include <mcheck.h> int main(int argc, char **argv) { setenv("MALLOC_TRACE", "memery_leak.log", 1); mtrace(); char *p1 = (char*)malloc(16); char* p2 = (char*)malloc(20); free(p1); p1 = NULL; muntrace(); return 0; }
編譯代碼,終端輸入命令:gcc -g main.c -o main.out
運(yùn)行程序,終端輸入:./main.out 命令。當(dāng)前目錄下就會(huì)生成 memory_leak.log 文件。
定位問題,終端輸入:mtrace main.out memory_leak.log 命令后,并沒有定位到 C 源碼的具體行數(shù),如下所示:
下面使用 地址轉(zhuǎn)化工具 addr2line 工具分析一下,上面地址是對(duì)應(yīng)到哪一行 C 代碼行。
如下所示:
可以看出,能夠猜到可能是后面的地址不對(duì)。導(dǎo)致 addr2line 工具轉(zhuǎn)換失敗。
網(wǎng)上百度到,可能的原因如下:
1. 關(guān)閉 Linux 系統(tǒng)的 ASLR 功能。
ASLR 功能全稱為 Address Space Layout Randomization,地址空間布局隨機(jī)化。
它將進(jìn)程的某些內(nèi)存空間地址進(jìn)行隨機(jī)化來增大入侵者預(yù)測(cè)目的地址的難度,從而降低進(jìn)程被成功入侵的風(fēng)險(xiǎn)。
2. 編譯源碼時(shí),加上 "-no-pie" 選項(xiàng)。
下來進(jìn)行具體的操作,操作如下:
(1)關(guān)閉 ASLR 功能:
輸入命令:cat /proc/sys/kernel/randomize_va_space ,查看 Linux 系統(tǒng)的 ASLR 值是 2,說明默認(rèn) ASLR 功能是開啟的。
設(shè)置 ASLR 的值:輸入命令 : echo 0 > /proc/sys/kernel/randomize_va_space
(2)加入 "-no-pie" 選項(xiàng)后重新編譯程序。輸入命令: gcc -g -no-pie main.c -o main.out
(3)然后運(yùn)行程序,終端輸入命令: ./main.out
(4)使用 mtrace 工具查看 新生成的 memory_leak.log 文件。
如下所示:
可以看到,定位到了 C 代碼中的具體行。
到此,mtrace 工具定位到 C 代碼的具體的 11 行代碼存在內(nèi)存泄露 。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
linux下使用cmake編譯安裝mysql的詳細(xì)教程
這篇文章主要介紹了linux下使用cmake編譯安裝mysql的詳細(xì)教程,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-10-10ubuntu16.04自動(dòng)設(shè)置行號(hào)的步驟詳解
這篇文章主要介紹了ubuntu16.04自動(dòng)設(shè)置行號(hào)的步驟,文中給大家提到了Ubuntu vi設(shè)置行號(hào)的方法,感興趣的朋友跟隨腳本之家小編一起看看吧2018-08-08CentOS7系統(tǒng)增加swap的操作方法實(shí)例
這篇文章主要給大家介紹了關(guān)于CentOS7系統(tǒng)增加swap的操作方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用CentOS7系統(tǒng)具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10在Windows的Apache服務(wù)器上配置對(duì)PHP和CGI的支持
這篇文章主要介紹了在Windows的Apache服務(wù)器上配置對(duì)PHP和CGI的支持,其中CGI腳本文中演示的為Perl示例,需要的朋友可以參考下2015-07-07Apache?Log4j2?遠(yuǎn)程代碼執(zhí)行漏洞分析+檢測(cè)+防護(hù)(最新推薦)
Apache?Log4j2是一款開源的Java日志框架,被廣泛地應(yīng)用在中間件、開發(fā)框架與Web應(yīng)用中,用來記錄日志信息,這篇文章主要介紹了Apache?Log4j2?遠(yuǎn)程代碼執(zhí)行漏洞分析+檢測(cè)+防護(hù)(最新推薦),需要的朋友可以參考下2024-07-07Ubuntu 14.04下Django和MySQL環(huán)境部署全過程
這篇文章主要介紹了Ubuntu 14.04下Django和MySQL環(huán)境部署全過程,文中通過一步步的安裝步驟介紹的很詳細(xì),相信對(duì)大家具有一定的參考借鑒價(jià)值,有需要的朋友們下面來一起來看看吧。2017-02-02