用dTrace捕捉記憶體分配於釋放

2021-05-24 01:42:00 字數 2897 閱讀 9446

posted on

七月 1, 2008

byarrowpig1979

dtrace是solaris 10中乙個非常強大的工具,有了它,不需要更改**,就可以「打入」程式內部「探聽」我所要知道的一切。其中乙個非常重要的就是記錄記憶體分配與釋放,然後方便我進一步的分析。

我們所要做的就是寫乙個很簡單的dtrace的指令碼,比如叫memlog.d

上王道:

pid$1:libc:malloc:entry    //->當malloc被呼叫的時候執行的動作

pid$1:libc:malloc:return     //->當malloc返回的時候

/self->trace == 1 && self->size > 0/     //->條件:只捕捉trace==1並且記憶體分配》0的動作

以上兩段**就能捕捉所有通過malloc來分配記憶體的情況。pid$1是乙個pid provider,用來探聽給定的程序,程序id 是呼叫dtrace 指令碼的第乙個引數。這樣我們就可以通過命令引數傳入我關心的程序id。

下面看記憶體釋放:->相信一看就懂了

pid$1:libc:free:entry

其實分配記憶體還有calloc和realloc,都是類似的:

pid$1:libc:realloc:entry

/self->trace == 1 && self->size > 0/

pid$1:libc:realloc:return

/self->trace == 1 && self->size > 0/

pid$1:libc:calloc:entry

/self->trace == 1 && self->size > 0/

pid$1:libc:calloc:return

/self->trace == 1 && self->size > 0/

好了,**貼完了,看看怎麼執行吧~假設我的程式名字叫jianxu_arrowpig

-bash-3.00$ ps -ef | grep jianxu_arrowpig

就可以拿到程序號,假設程序id=6666

執行dtrace:

-bash-3.00$ dtrace -s memlog.d 6666

給一段例項輸出吧:

-bash-3.00$ sudo dtrace -s memlog.d 6666   //–>我這裡用sudo是因為dtrace 需要 root執行許可權。

dtrace: script 『mallco.d』 matched 7 probes

cpu     id                    function:name

0    534                    malloc:return ptr=0×9890130 size=20 ts=27532231842644751 alloctime=2008 jun 27 02:25:17

libc.so.1`malloc+0×49

scrubber`_zn23partitionoutputdbaction4initev+0x69a

scrubber`_zn23partitionoutputdbactionc1ep7xmlnode+0x10b6

scrubber`_z26parsesearchtransformationsp7xmlnodepfvpkce+0×3442

scrubber`_z8readfiler10filereader+0x3fb

scrubber`_z10refreshxmlpkc+0xc4

scrubber`_z13daemonprocessv+0x1f9b

scrubber`main+0xbd6

scrubber`_start+0×80

注意,給出的 trace是c++ mangled的symbol如果要看unmangled name:

-bash-3.00$ gc++filt _zn23partitionoutputdbactionc1ep7xmlnode

partitionoutputdbaction::partitionoutputdbaction(xmlnode*)

通常我會重定向輸出,這樣可以用perl做offline的分析:

-bash-3.00$ sudo dtrace -s memlog.d 6666 > mem.log

還真巧了,今天就在查memory leak.

egrep 『malloc:return|free:entry』 mem.log > mem.log.******  //–>先弄個小點的

cat mem.log.****** | perl memanalyze.pl > memleak.log

##memanalyze.pl ##寫了個很傻的,不知道好用不好用

#! /usr/bin/perl -wuse strict;use warnings;

my $line;

my %result;

while ($line=)

if(  $line=~/malloc/:return/sptr=0x([0-9a-f]+)/ssize=(/d+)/sts=(/d+)/)  

#use ptr as the key, hash value is ts, so i can locate in the original log       

$result= $3;   

elsif( $line=~/free/:entryn/sptr=0x([0-9a-f]+)/ssize=(/d+)/sts=(/d+)/)  

delete $result;  #delete the entry   

my $myptr;

my $myts;

while ( ($myptr, $myts) = each %result)

print "ptr=0x$myptr, ts=$myts/n";

記憶體分配失敗捕捉 set new handler

當記憶體分配請求不能滿足時,呼叫你預先指定的乙個出錯處理函式。這個方法基於乙個常規,即當operator new不能滿足請求時,會在丟擲異常之前呼叫客戶指定的乙個出錯處理函式 一般稱為new handler函式。operator new實際工作起來要複雜一些,詳見條款8 指定出錯處理函式時要用到 s...

用calloc 函式分配記憶體

用calloc 函式分配記憶體 calloc函式原型 void calloc size t num elements,size t element size 在標頭檔案中宣告的calloc 函式與malloc 函式相比有兩個優點。第一,它把記憶體分配為給定大小的陣列,第二,它初始化了所分配的記憶體,...

cpp(2)引用const動態記憶體分配

1 引用 很多書描述引用為乙個變數或物件的乙個別名 alias 成為該變數或 物件的同義詞,然而,實際上引用是 別名其表,指標其實 也即,引用 實質上是乙個指標,但使用時卻像乙個別名。2 引用的主要用途 a 用作函式引數,用於傳遞大型物件,必要時可從函式內部 修改函式外部的實參。此功能和指標相同,b...