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...