Linux下使用valgrind做内存泄露检测及绘制函数调用图

来源:互联网 发布:手机淘宝外卖 编辑:程序博客网 时间:2024/05/01 09:02

 

Linux下使用valgrind做内存泄露检测及绘制函数调用图

 

1、安装

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

 

2、使用memcheck检测内存泄露

示例: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.cpg参数会生成gmon.out文件,可用于profcallgrind使用)

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

 

 

3、使用callgrind生成调用图

示例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