Linux下使用valgrind做内存泄露检测及绘制函数调用图
wget http://valgrind.org/downloads/valgrind-3.4.1.tar.bz2
tar –xvf valgrind-3.4.1.tar.bz2
cd valgrind-3.4.1
./configure --prefix=/usr/local/valgrind
make
make install
示例:leak.c
#include <stdio.h>
#include <stdlib.h>
void f(void)
{
int* x = malloc(10 * sizeof(int));
x[10] = 0; // problem 1: heap block overrun
} // problem 2: memory leak -- x not freed
int main(void)
{
int i=0;
f();
printf("i=%d/n",i); //problem 3:use uninitialised value.
return 0;
}
步骤:
gcc -o leak leak.c
(或者使用gcc -pg -o leak.c,pg参数会生成gmon.out文件,可用于prof或callgrind使用)
/usr/local/valgrind/bin/valgrind --tool=memcheck --leak-check=full leak
说明:
--tool=memcheck:使用memcheck工具
--leak-check:
user options for Memcheck:
--leak-check=no|summary|full search for memory leaks at exit? [summary]
--leak-resolution=low|med|high how much bt merging in leak check [low]
--show-reachable=no|yes show reachable blocks in leak check? [no]
--undef-value-errors=no|yes check for undefined value errors [yes]
--track-origins=no|yes show origins of undefined values? [no]
--partial-loads-ok=no|yes too hard to explain here; see manual [no]
--freelist-vol=<number> volume of freed blocks queue [10000000]
--workaround-gcc296-bugs=no|yes self explanatory [no]
--ignore-ranges=0xPP-0xQQ[,0xRR-0xSS] assume given addresses are OK
--malloc-fill=<hexnumber> fill malloc'd areas with given value
--free-fill=<hexnumber> fill free'd areas with given value
--alignment=<number> set minimum alignment of allocations [8]
打印结果:
==11270== Memcheck, a memory error detector.
==11270== Copyright (C) 2002-2008, and GNUGPL'd, by Julian Seward et al.
==11270== Using LibVEX rev 1884, a libraryfor dynamic binary translation.
==11270== Copyright (C) 2004-2008, and GNUGPL'd, by OpenWorks LLP.
==11270== Using valgrind-3.4.1, a dynamicbinary instrumentation framework.
==11270== Copyright (C) 2000-2008, and GNUGPL'd, by Julian Seward et al.
==11270== For more details, rerun with: -v
==11270==
==11270== Invalid write of size 4
==11270== at 0x4004F6: f (in /usr/local/valgrind/leak)
==11270== by 0x400511: main (in /usr/local/valgrind/leak)
==11270== Address 0x4c25058 is 0 bytes after a block of size 40 alloc'd
==11270== at 0x4A05FBB: malloc (vg_replace_malloc.c:207)
==11270== by 0x4004E9: f (in /usr/local/valgrind/leak)
==11270== by 0x400511: main (in /usr/local/valgrind/leak)
i=0/n==11270==
==11270== ERROR SUMMARY: 1 errors from 1contexts (suppressed: 10 from 1)
==11270== malloc/free: in use at exit: 40bytes in 1 blocks.
==11270== malloc/free: 1 allocs, 0 frees,40 bytes allocated.
==11270== For counts of detected errors,rerun with: -v
==11270== searching for pointers to 1not-freed blocks.
==11270== checked 63,656 bytes.
==11270==
==11270==
==11270== 40 bytes in 1blocks are definitely lost in loss record 1 of 1
==11270== at 0x4A05FBB: malloc(vg_replace_malloc.c:207)
==11270== by 0x4004E9: f (in/usr/local/valgrind/leak)
==11270== by 0x400511: main (in/usr/local/valgrind/leak)
==11270==
==11270== LEAK SUMMARY:
==11270== definitely lost: 40 bytes in 1 blocks.
==11270== possibly lost: 0 bytes in 0 blocks.
==11270== still reachable: 0 bytes in 0 blocks.
==11270== suppressed: 0 bytes in 0 blocks.
示例temp.c文件:
#include <stdio.h>
#include <malloc.h>
void test()
{
sleep(1);
}
void f()
{
int i;
for( i = 0; i < 5; i ++)
test();
}
int main()
{
f();
printf("process is over!\n");
return 0;
}
步骤:
cd /usr/local/valgrind
#生成分析文件(形如callgrind.out.xxx)
bin/valgrind --tool=callgrind ./temp
#基于分析文件生成call图(使用了gprof2dot.py脚本)
python gprof2dot.py -f callgrindcallgrind.out.XXX |/usr/local/graphviz/bin/dot -Tpng -o report.png
#发送到本机查看图形
sz report.png
参考:使用linux自带工具gprof分析temp.o文件,并使用gprof2dot.py生成dot文件,再使用dot工具生成图形:
gcc –pg –o temp temp.c #编译temp.c
gprof temp |python gprof2dot.py|/usr/local/graphviz/bin/dot -Tpng -o report2.png #这里使用管道命令“|”将输入进行传递
sz report2.png #发送到本机查看图形
分析temp.c生成的图形:
1、生成调用图需要安装支持dot语言的工具包Graphviz
cd /home/memcheck
wgethttp://www.graphviz.org/pub/graphviz/stable/SOURCES/graphviz-2.26.3.tar.gz
tar –zxvf graphviz-2.26.3.tar.gz
./configure LDFLAGS="-L/usr/lib64-L/lib64" -prefix=/usr/local/graphviz/
make && make install
在make时遇到问题:/usr/lib/libexpat.so: could not readsymbols: File in wrong format
解决方法:在configure后的选项中加上:LDFLAGS="-L/usr/lib64-L/lib64",所以上面的configure配置应该是这样的:
./configure LDFLAGS="-L/usr/lib64-L/lib64" -prefix=/usr/local/graphviz/
使用dot生成图形
安装dot的目录为:/usr/local/graphviz
使用方法:/usr/local/graphviz/bin/dot-Tpng -o report.png prcess.gv
其中,process.gv文件为:
graph G {
run-- intr;
intr -- runbl;
runbl -- run;
run-- kernel;
kernel -- zombie;
kernel -- sleep;
kernel -- runmem;
sleep -- swap;
swap -- runswap;
runswap -- new;
runswap -- runmem;
new-- runmem;
sleep -- runmem;
}
输出图形如下:
参考graphviz安装:http://wuliangxx.iteye.com/blog/656856
参考 dot语言:http://zh.wikipedia.org/zh-cn/DOT%E8%AF%AD%E8%A8%80
dot绘图:http://blog.linuxeden.com/index.php/225479/viewspace-7749.html
下载gprof2dot(这款应该比较新):http://code.google.com/p/jrfonseca/wiki/Gprof2Dot#Download
下载gprof2dot后修改其中一行代码:"except xml.parsers.expat.ExpatError as e:"改为:"except xml.parsers.expat.ExpatError , e:"
valgrind官方文档:http://valgrind.org/docs/manual/index.html