Valgrind内存检测工具的使用
本文对Valgrind内存检测工具的使用方法作一个简单的记录,其内容大部分来自官方手册,将持续更新,建议收藏。
下载
- 源码链接:https://www.valgrind.org/downloads/current.html.
- 手册下载:https://www.valgrind.org/docs/download_docs.html.
安装
- ./autogen,sh(若出现while running ’ aclocal ’ ,autogen.sh :1:eval:aclocal :not found,先执行sudo apt-get install automake,安装必要的依赖和库,即可解决。)
- ./configure --prefix=$(path) (若是在嵌入式环境运行,需要指明交叉编译工具链–host=armv7-linux CC=xxx-gcc CPP=xxx-cpp CXX=xxx-g++等相关信息,如果–host=arm-linux,执行configure的时候会出现error: Unsupported host architecture.Sorry,当然也可以改configure文件配置,arm7*改成arm7*|arm)
- make
- make install
调用方式[command-line]
valgrind [valgrind-options] your-prog [your-prog-options]
参数介绍[valgrind-options]
- –tool=<tool_name>:指定工具名称,memcheck, cachegrind, callgrind, helgrind, drd, massif, dhat, lackey, none, exp-bbv, etc,默认使用memcheck工具-
- –gen-suppressions=yes:为每个报告的错误打印出抑制结果
- –num-callers=<number>: 增大堆栈信息输出
- –track-origins=yes :是否显示未定义的变量,在堆、栈中被定义没有被initialised的变量都被定义成origins。默认是关闭这个option的。
- –leak-check=<no|summary|full> :当服务器退出时是否收集输出内存泄漏,默认将会使用summary方式。
- –log-file=<fiilname>:指定报告输出文件
- –log-fd=<文件描述符>:默认为2(stderr),和–log-file效果差不多,个人推荐使用–log-file
- –log-socket=<ip:port>:将信息通过网络发送给特定ip和port,若省略端口号,将使用默认端口1500。默认值由源中的常量VG_CLO_DEFAULT_LOGPORT定义。
- –read-inline-info=yes:读取内联信息的调试信息,这样即使内联编译应用程序,函数的调用链也会正确显示
- –read-var-info= [default: no]:启用后可以使valgrind读取变量类型和定义位置等相关信息,比如可以检测到一个未初始化的变量,该变量是一个int型的全局变量,在main.c的第10行被定义。
- -v 参数:执行完成后,所有报告都将被打印出来,例如加载的共享对象,使用的抑制,检测和执行引擎的进度以及有关异常行为的警告。并按其出现次数进行排序,这样可以很容易地查看哪些错误最常发生。
- -q,–quit:以静默方式运行,仅打印错误消息。
- –error-limit=no :保证valgrind会无限制的显示错误,因为考虑到对运行效率的影响,valgrind默认超过1000个不同错误或10000000(一千万)个错误就会停止收集错误,所以这个选项也需要谨慎使用,否则会对性能产生影响。
工具模块
- Memcheck是内存错误检测器。它可以帮助您使程序,尤其是用C和C ++编写的程序更加正确。
- Cachegrind是一个缓存和分支预测探查器。它可以帮助您使程序运行更快。
- Callgrind是一个生成调用图的缓存分析器。它与Cachegrind有一些重叠,但也收集了Cachegrind没有的一些信息。
- Helgrind是线程错误检测器。它可以帮助您使多线程程序更正确。
- DRD还是线程错误检测器。它类似于Helgrind,但使用不同的分析技术,因此可能会发现不同的问题。
- Massif是堆分析器。它可以帮助您减少程序使用的内存。
- DHAT是另一种堆分析器。它可以帮助您了解模块寿命,模块利用率和布局效率低下的问题。
- BBV是一个实验性的SimPoint基本块矢量生成器。这对从事计算机体系结构研究和开发的人员很有用。
注意事项
- 编译自己的程序,需要加上 -g 参数,以生成调试信息,这样在使用valgrind进行分析的时候,您将获得直接指向相关源代码行的消息。
- 如果使用的是C++,则可能要考虑的另一个选项是 -fno-inline 。这样更容易查看函数调用链,该函数链可帮助减少在大型C ++应用程序中导航时的混乱。
- 若编译的时候加上了-O2或者是-O1参数,会使编译优化,会生成使Memcheck误报未初始化值错误或遗漏未初始化值错误的代码。要么完全关闭优化,要么使用-O参数,可以有较高优化并且减少误报。
- 编译时需要加上 -Wall 参数,因为它可以识别Valgrind在较高的优化级别上可能会遗漏的部分或全部问题。所有其他工具均不受优化级别的影响,对于Cachegrind之类的性能分析工具,最好以其常规优化级别编译程序。
局限
- Memcheck无法检测到程序存在的每个内存错误。例如,它无法检测对静态分配或在堆栈上分配的数组的超出范围的读取或写入。但是它应该检测到许多可能导致程序崩溃的错误(例如,段错误)。
No pains, no gains.