Valgrind是一款用来帮助程序员查找/定位内存使用问题的免费/开源动态分析工具。实际上,valgrind的功能不仅仅只是内存错误检测,工具集中还带有有线程错误检测/缓存和分支预测分析器/调用关系图生成缓存和分枝预测分析器/堆(heap)分析器。此外,Valgrind工具集中还包含了一些如堆/栈/全局数组越界检查器等其他工具。
Valgrind的官方网址:http://valgrind.org/
1. 安装
Ubuntu下可以使用新立德软件管理器/apt-get安装;或者下载源码自行编译安装。
手工编译安装
svn co svn://svn.valgrind.org/valgrind/trunk valgrind
cd valgrind
./autogen.sh
./configure --prefix=`pwd`
make
make install
cd valgrind
./autogen.sh
./configure --prefix=`pwd`
make
make install
2. 工作原理
检测时,Valgrind读入程序和相关库文件的调试信息(如果有),在所关心的敏感操作前后插入自己的检测代码,然后将程序放到一个虚拟的CPU中运行以捕获任何可能的错误。
3. 对待测程序的要求
编译选项:
- 推荐使用-g使gcc将调试信息包含进目标程序中,这样Valgrind可以将捕获到的错误精确定位到源代码的行;
- 推荐使用-O0关闭gcc优化;-O1编译出的程序大部分情况下也能正常工作在Valgrind之下,但定位出的错误所在行编号可能会不太准确;-O2及以上优化级别将可能使Valgrind错误不可信。
4. 使用Valgrind进行内存错误检测
命令
valgrind [options] your_program [your_program_arguments]
Valgrind选项中最基本也是最重要的选项是选择Valgrind的功能--tool=tool_name,tool_name可以为memcheck,cachegrind,helgrind,callgrind...。
Valgrind缺省将工具设为内存检查(memcheck)方式。常用内存检查选项
- --leak-check=<no|summary|yes|full> :当程序结束时给出内存泄露的总量;'yes'或'full'则会给出每一处泄露的详细信息;缺省为summary
- --leak-resolution=<low|med|high> :决定报告中内存泄露合并条件的宽松度;缺省为high
- --show-reachable=<yes|no> :是否在"definitely lost"和"possibly lost"类型的内存泄露之外,额外给出"reachable"和"indirectly lost"块的信息;缺省为'no'
-
--undef-value-errors=
<yes|no> :是否给出"undefined value"错误信息;缺省为'yes'
- --track-origins=<yes|no> :是否追踪未初始值的出处;缺省为'no'
- --freelist-vol=<number> :一般地,使用free或delete所释放的内存并不能立刻就被重新分配使用,而是会被标记为不可访问并放置在空闲块队列之中。freelist-vol选项设置这个空闲块队列的最大尺寸,单位为M;默认值为10M
- --malloc-fill=<hexnumber> :使用指定值填充malloc/new等操作(不包括calloc)所分配到内存块
- --free-fill=<hexnumber> :使用指定值填充将被free/delete所释放的内存块
- ...
两个其它选项
- 默认条件下,Valgrind仅对最顶层的进程进行检测,而忽略子进程。使用选项--trace-children=yes可予以纠正;
- 默认条件下,Valgrind不会对静态数组或位于栈内的的数组进行边界检查。不过可以使用选项--tool=exp-ptrcheck可予以纠正(但不保证此方法的健状性);
5. Valgrind的不足
截止目前版本
- Valgrind不能对程序中使用fork()方式产生的子进程进行有效检测(但对exec系列函数产生的子进程有效);
- 对多线程程序,Valgrind使用的线程调度算法/线程所用内存的规划等,都和真实系统有所不同。因此,对对多线程程序,Valgrind未检测到错误并不能说明程序中不存在问题(如多线程间的数据竞争问题(data racing))
更多Valgrind选项说明及使用方法,可以参考Valgrind