valgrind进行内存检查

valgrind可以检查内存泄露、越界等

参考:

http://www.cnblogs.com/wangkangluo1/archive/2011/07/20/2111248.html

http://blog.csdn.net/sduliulun/article/details/7732906

用valgrind进行内存检查:

1.拷贝程序库的debug版本包(包括libc,libpthread,libm等各种基础库的debug版本)到usr/lib/debug目录。目的是让valgrind能找到程序所用库的符号表,valgrind需要用到来根据内存中的块标记找到它的申请者函数
tar zxvf debug-mv.tar.gz -C /usr/lib

2.拷贝valgrind程序到/usr目录:(如果target的flash存储不足,放/usr下会有问题,可以把/usr/lib/valgrind放到U盘里并第3步相应设置环境变量。U盘重新mount变可写:mount -o remount rw /media/F728-B202/)
tar zxvf valgrind3.tar.gz -C /usr
3.环境变量设置
vi /etc/profile:
export PATH=\
......
/usr/lib/valgrind
export VALGRIND_LIB=/usr/lib/valgrind
4.测试下: valgrind test,test是一个target上的小程序。
注意:valgrind3.tar.gz比较大,解压时会有/目录空间不够的情况导致解压失败,需要删除一些/下面的东西。或者把valgrind3.tar.gz安装包放在U盘中,从U盘中解压到/usr目录下,可以省去压缩包的空间
使用memcheck工具并以文件输出信息:valgrind -v --tool=memcheck --leak-check=full --log-file=result.txt /root/test
其中-v是显示verbose信息,--leak-check=full显示详细的泄露信息,/root/test为被调试程序,必须为绝对路径

注意valgrind 后面不加--tool=***时,默认使用的就是memcheck工具。memcheck工具对于运行一段时间自动退出的程序有用,但对于一直在后台执行的程序难以分析
6.调试后台一直执行的程序:

首先,后台一直执行的程序用memcheck工具是难以分析的,需要用massif工具。其次,程序需要以valgrind方式启动

方式1:修改自启动systemd配置文件,用执行valgrind的脚本文件名替代程序名,如test.sh。要当心内存不够导致valgrind执行失败,用memcheck工具会有这种情况,用massif会好些
方式2:手动kill掉程序后,打开dbus(根据target对程序的使用情况,程序正常运行依赖的东西要设置好,可以):
eval export `cat /var/tmp/dbus_session.conf`
然后执行valgrind启动程序:
valgrind -v --tool=massif /usr/bin/yourProgram
由于target配置不高而valgrind消耗资源很大(大约100M内存),所以启动的时间很长,要将近1分钟,并且会比较卡。多等等看,可以根据valgrind的打印或程序自身的log打印看起来没有。
执行结果massif.out.%pid会保存在当前目录。因为生成的文件比较大有几兆到几十兆,target上放不下,所以可以在u盘目录下执行来让文件写到U盘。mount -o remount rw /media/F728-B202/
7.查看结果:massif工具的检查结果可以在Ubuntu上用massif-visualizer查看,参考http://blog.csdn.net/tao_627/article/details/44982765
结果图右边每个snapshort节点显示的,是当前的堆里面所有内存都是被谁分配的。可以查看每块的使用量,比对多个snapshort中哪块内存的使用量一直在上升来查看哪个内存一直在增长。左边的图更直观地显示每块内存的增长情况,一个颜色的区域代表了一个函数申请的内存的情况。


8.补充的内存泄露检查技巧:

有些时候即使知道哪里申请的没释放也仍然难查,例如使用sqlite3,sqlite3里面有内存申请没释放,这种情况其实是外部调用sqlite3的地方使用不当导致。sqlite3里面释放的地方就是sqlite3_finalize函数,每个sqlite3_prepare(或sqlite3_prepare_v2),都要对应一个sqlite3_finalize。

对这样的情况:

1.现在关键函数里面加计数器,确认是这里调用不当泄露,例如sqlite3_prepare_v2, sqlite3_finalize中各加计数,运行一段时间后看两者调用次数是否相等。如果差别越来越大那肯定就是对它们的调用出了问题。

你可能感兴趣的:(linux)