mtrace-內(nèi)存使用追蹤(內(nèi)存)

1. 函數(shù)格式:

       #include <mcheck.h>

       void mtrace(void);

       void muntrace(void);

mtrace 用于開啟內(nèi)存使用記錄屉佳,muntrace用于取消內(nèi)存使用記錄把敢。內(nèi)存使用情況記錄到一個文件钞楼,值由環(huán)境變量:MALLOC_TRACE決定。

2. 范例:

#include <stdlib.h>
#include <stdio.h>
#include <mcheck.h>

int main(int argc, char **argv)
{
        mtrace();

        char * p = malloc(100);

        free(p);

        p = malloc(1000);

        muntrace();

        return 0;
}

編譯:
$ gcc mtrace.c -g
加上 -g 參數(shù)蒸眠,在程序中記錄調(diào)試信息漾橙。是為了后面進行程序地址轉(zhuǎn)換為代碼文件位置。

導(dǎo)出內(nèi)存記錄文件路徑的環(huán)境變量:
$ export MALLOC_TRACE=/home/centos/gnuc/c3/trace.log

運行結(jié)果:

$ ./a.out

$ cat trace.log
= Start
@ ./a.out:[0x40062b] + 0xf15460 0x64
@ ./a.out:[0x40063b] - 0xf15460
@ ./a.out:[0x400645] + 0xf154d0 0x3e8
= End

3. 分析結(jié)果:

從記錄文件可以看出楞卡,其格式如下:
@ 程序名稱:[內(nèi)存分配調(diào)用的地址] +/- 操作的內(nèi)存地址 部分參數(shù)
+ 表示分配霜运;- 表示釋放

可以使用 mtrace 命令來分析記錄文件脾歇。mtrace 命令是 glibc-utils 的工具,是一個 perl 腳本文件淘捡,通過調(diào)用 addr2line 命令來進行解析代碼文件位置藕各。如果無該命令,可以安裝 glibc-utils 來安裝該命令焦除。

使用mtrace命令分析:

$ mtrace a.out trace.log
Memory not freed:
-----------------
           Address     Size     Caller
0x00000000013fc4d0    0x3e8  at /home/centos/gnuc/c3/mtrace.c:13

mtrace 函數(shù)是通過修改 malloc_hook 等內(nèi)存操作接口的回調(diào)來實現(xiàn)記錄內(nèi)存使用的座韵。如何取得內(nèi)存分配函數(shù)的調(diào)用地址呢?gcc 有一個內(nèi)置的函數(shù)踢京,用于返回本函數(shù)將要返回的地址。

內(nèi)置返回地址函數(shù):

void * __builtin_return_address (unsigned int level);

返回的是處于 level 級堆棧的地址宦棺。 level 為 0 表示本函數(shù)返回的地址瓣距,為 1 表示本函數(shù)的上一個函數(shù)返回的地址,依次類推代咸。
該函數(shù)細節(jié)可參考:gcc online 文檔

范例:

#include <stdio.h>

int test(int argc, char **argv)
{
        void *ret =  __builtin_return_address(0);
        printf("%p\n", ret - 1); 

        void *caller = __builtin_frame_address(0);

        printf("%p\n", caller);
        return 0;
}

int main(int argc, char **argv)
{
        test(argc, argv);
        return 0;
}

內(nèi)置函數(shù)返回的是本函數(shù)返回的地址蹈丸,是函數(shù)調(diào)用的下一條語句,所以使用ret - 1來記錄函數(shù)被調(diào)用地址呐芥。

編譯:
$ gcc retaddr.c -g

運行結(jié)果:

$ ./a.out
0x40059e
0x7ffdb38621f0

將地址轉(zhuǎn)換為代碼位置:

$ addr2line -f -e a.out -a 0x40059e
0x000000000040059e
main
/home/centos/gnuc/c3/retaddr.c:16

4. 使用場景:

mtrace 采用 malloc_hook + return_addr 這兩個機制來實現(xiàn)的逻杖。

  1. mtrace 會記錄所有的分配、釋放思瘟,包括所有的模塊荸百、線程。內(nèi)存使用記錄必將很多滨攻,所以官方推薦使用 SIGUSR1SIGUSR2 來進行開啟和關(guān)閉內(nèi)存記錄功能够话。
  2. mtrace 記錄和分析結(jié)果可以看到,內(nèi)存記錄日志只記錄到 malloc 層面光绕。而實際項目開發(fā)時女嘲,很多接口都是封裝多層才會實際調(diào)用到 malloc,對于上面幾層的地址欣尼,mtrace 沒有記錄愕鼓。而上面幾層的調(diào)用關(guān)系才是追蹤內(nèi)存泄漏問題的關(guān)鍵所在慧起。所以在實際開發(fā)的項目中拒啰,使用 mtrace 不是一個特別好的方法。這里推薦使用 valgrind 工具進行跑流程的方式追蹤內(nèi)存泄漏完慧。如果想要自己記錄內(nèi)存使用情況,可以考慮以下兩種方式:
  1. 封裝一層內(nèi)存分配册着、釋放的接口函數(shù)來記錄內(nèi)存使用情況。項目開發(fā)時演熟,統(tǒng)一使用這個接口來進行內(nèi)存管理司顿。適用于項目尚未開始。
  2. 使用 malloc_hook 的方式進行記錄化漆,項目代碼可以不變钦奋。適合于項目已經(jīng)比較龐大了。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末朦拖,一起剝皮案震驚了整個濱河市璧帝,隨后出現(xiàn)的幾起案子裸弦,更是在濱河造成了極大的恐慌作喘,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窖贤,死亡現(xiàn)場離奇詭異赃梧,居然都是意外死亡豌熄,警方通過查閱死者的電腦和手機锣险,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巷折,“玉大人,你說我怎么就攤上這事油吭∈鹉猓” “怎么了推穷?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵缨恒,是天一觀的道長骗露。 經(jīng)常有香客問我血巍,道長述寡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮螟炫,結(jié)果婚禮上昼钻,老公的妹妹穿的比我還像新娘。我一直安慰自己仅财,他們只是感情好盏求,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布风喇。 她就那樣靜靜地躺著魂莫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谜喊。 梳的紋絲不亂的頭發(fā)上斗遏,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天诵次,我揣著相機與錄音逾一,去河邊找鬼遵堵。 笑死陌宿,一個胖子當(dāng)著我的面吹牛波丰,可吹牛的內(nèi)容都是我干的壳坪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼掰烟,長吁一口氣:“原來是場噩夢啊……” “哼弥虐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起霜瘪,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤惧磺,失蹤者是張志新(化名)和其女友劉穎颖对,沒想到半個月后顾患,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體江解,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年酿秸,在試婚紗的時候發(fā)現(xiàn)自己被綠了辣苏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡稀蟋,死狀恐怖煌张,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情糊治,我是刑警寧澤唱矛,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布管闷,位于F島的核電站粥脚,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏包个。R本人自食惡果不足惜刷允,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望碧囊。 院中可真熱鬧树灶,春花似錦、人聲如沸糯而。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽熄驼。三九已至像寒,卻和暖如春烘豹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背诺祸。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工携悯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人筷笨。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓憔鬼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親奥秆。 傳聞我的和親對象是個殘疾皇子逊彭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容