Valgrind介绍
Valgrind是构建动态分析工具的一个框架。它里面有一系列用于调试、分析程序的工具集。各种工具是以模块的形式存在,所以可以非常轻松的增加新的工具而不影响现有的框架。下面是一些默认支持的常用工具:
- Memcheck 内存错误检测工具,他可以帮助你检测程序中的内存错误,特别适用于C和C++写的程序。
- Cachegrind 缓存和分支预测分析工具,他可以帮助你优化程序,使程序运行的更加高效。
- Callgrind 函数调用分析工具,他和Cachegrind工具有些相似,但是他可以统计一些Cachegrind工具无法统计的信息。
- Helgrind 线程错误检测工具,他可以帮助你检测多线程程序中的问题。
- DRD 也是一个线程错误检测工具,但是它使用不同的分析技术,可以检测出和Helgrind工具不同的问题。
- Massif 堆分析工具,可以帮助你减少程序的内存使用量。
- DHAT 另一种堆分析工具,可以帮助你了解内存块的生命周期、利用率和内存布局。
- SGcheck 他可以检测栈或者数组访问超限的问题,他是Memcheck工具的一个补充,可以检测出Memcheck工具检测不到的问题。
Valgrind被尽量设计为非侵入式的工具,可以直接调试二进制的可执行程序。不需要为了使用Valgrind而重新编译、链接或者修改代码。使用如下形式的命令运行Valgrind:
valgrind [valgrind-options] your-prog [your-prog-options]
其中最重要的选项是--tool
它指定了使用Valgrind中的哪个工具。举个例子,如果你想使用内存检测工具Memcheck来检测ls -l
命令,可以输入如下命令:
valgrind --tool=memcheck ls -l
当然Memcheck是默认工具,所以当你使用Memcheck工具时可以不加--tool
选项。
Valgrind的输出信息格式如下:
==12345== some-message-from-Valgrind
其中12345
是进程的ID,Valgrind默认只会打印一些必要的信息,你也可以使用-v
选项打印详细信息,或者使用--log-file=filename
来将打印信息输出到一个文件中,也可以使用--log-socket=192.168.0.1:12345
选项将打印信息通过网络传输到指定地址。命令示例:
valgrind --tool=memcheck -v ls -l
valgrind --tool=memcheck --log-file=filename ls -l
valgrind --tool=memcheck --log-socket=192.168.0.1:12345 ls -l
Memcheck内存检测工具
Memcheck内存检测工具,可以检测C和C++程序中的下面问题:
- 访问非法内存。例如:越界访问块内存、越界访问栈内存、访问已经被释放的内存。
- 使用未定义的值。例如:没有被初始化的值。
- 不正确的堆内存释放。例如:多次释放同一内存块或者分配内存的函数和释放内存的函数不一致,
malloc/new/new[]
分别对应free/delete/delete[]
。 - 传递给
memcpy
一类的函数中src
和dst
指针所指向的内存有重叠。 - 内存泄漏
- 传递不正确的值给内存分配函数的
size
参数。
--leak-check=<no|summary|yes|full> [default: summary]
使用了此选项时,当程序运行结束后会统计内存泄漏信息。如果设置为summary
则会显示发生了多少次内存泄漏事件,如果设置为full
或者yes
,每个内存泄漏事件都会显示详细信息并把它记为错误。如同指定了--show-leak-kinds
和--errors-for-leak-kinds
选项一样。
valgrind --tool=memcheck --leak-check=full ./str_replace
输出如下统计信息
==27497== HEAP SUMMARY:
==27497== in use at exit: 1,024 bytes in 1 blocks
==27497== total heap usage: 1 allocs, 0 frees, 1,024 bytes allocated
==27497==
==27497== 1,024 bytes in 1 blocks are definitely lost in loss record 1 of 1
==27497== at 0x4C267CE: malloc (vg_replace_malloc.c:236)
==27497== by 0x400843: main (in /ac/str_replace)
==27497==
==27497== LEAK SUMMARY:
==27497== definitely lost: 1,024 bytes in 1 blocks
==27497== indirectly lost: 0 bytes in 0 blocks
==27497== possibly lost: 0 bytes in 0 blocks
==27497== still reachable: 0 bytes in 0 blocks
==27497== suppressed: 0 bytes in 0 blocks
==27497==
==27497== For counts of detected and suppressed errors, rerun with: -v
==27497== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)