一、什么是valgrind
valgrind是一款运行在linux下的,用来定位c/c++程序中内存使用方面的错误的工具,包括:内存泄漏、使用未初始化的内存、读/写已释放的内存、读/写内存越界、使用malloc/new/new[]和free/delete/delete[]不匹配,等等。
Valgrind是帮助程序员寻找程序里的bug和改进程序性能的工具。程序通过valgrind运行时,valgrind收集各种有用的信息,通过这些信息可以找到程序中潜在的bug和性能瓶颈。
二、valgrind的安装
解压安装包:tar–jxvfvalgrind3.3.1.tar.bz2
解压后生成目录valgrind-3.3.1
cd valgrind-3.3.1
./configure
make
make install
好了,现在已经安装好了valgrind,可以开始了解如何使用它了。 三、valgrind的工具介绍
valgrind默认使用memcheck工具,即默认参数
--tools=memcheck
memcheck
这个工具可以用来寻找c、c++程序中内存管理的错误。写c或c++程序时,很多隐藏很深的bug是内存操作上出了问题,而这些在Memcheck面前都无处遁形。
Memcheck可以检查出下列几种内存操作上的错误:
要求用gcc编译时使用-g选项
例如对test.c程序进行编译:gcc-g -o test test.c
valgrind [option] exefile arg...
[option]:参数选项
exefile:可执行程序
arg...:程序参数
option参数必须加上--leak-check=yes
举例:以程序test为例,检查test程序内存错误:
valgrind--leak-check=yes ./test
5.1基本选项:这些选项对所有工具都有效
显示所有选项的帮助,包括内核和选定的工具两者。
和--help相同,并且还能显示通常只有Valgrind的开发人员使用的调试选项。
显示Valgrind内核的版本号。工具可以有他们自已的版本号。这是一种保证工具只在它们可以运行的内核上工作的一种设置。这样可以减少在工具和内核之间版本兼容性导致奇怪问题的概率。
安静的运行,只打印错误信息。在进行回归测试或者有其它的自动化测试机制时会非常有用。
显示详细信息。在各个方面显示你的程序的额外信息,例如:共享对象加载,使用的重置,执行引擎和工具的进程,异常行为的警告信息。重复这个标记可以增加详细的级别。
运行toolname指定的Valgrind,例如,Memcheck,Addrcheck,Cachegrind,等等。
当这个选项打开时,Valgrind会跟踪到子进程中。这经常会导致困惑,而且通常不是你所期望的,所以默认这个选项是关闭的。
当这个选项打开时,Valgrind会在退出时打印一个打开文件描述符的列表。每个文件描述符都会打印出一个文件是在哪里打开的栈回溯,和任何与文件描述符相关的详细信息比如文件名或socket信息。
当这个选项打开时,每条信息之前都有一个从程序开始消逝的时间,用天,小时,分钟,秒和毫秒表示。
指定Valgrind把它所有的消息都输出到一个指定的文件描述符中去。默认值2, 是标准错误输出(stderr)。注意这可能会干扰到客户端自身对stderr的使用,Valgrind的输出与客户程序的输出将穿插在一起输出到stderr。
类似于--log-file,但是后缀“.pid”不会被添加。如果设置了这个选项,使用Valgrind跟踪多个进程,可能会得到一个乱七八糟的文件。
指定Valgrind输出所有的消息到指定的IP,指定的端口。当使用1500端口时,端口有可能被忽略。如果不能建立一个到指定端口的连接,Valgrind将输出写到标准错误(stderr)。这个选项经常和一个Valgrind监听程序一起使用。
5.2 错误相关选项:这些选项适用于所有产生错误的工具,比如Memcheck, 但是Cachegrind不行。
当这个选项打开时,输出将是XML格式。只有Memcheck时生效。
在XML开头附加用户注释,仅在指定了--xml=yes时生效,否则忽略。
默认情况下,Valgrind显示12层函数调用的函数名有助于确定程序的位置。可以通过这个选项来改变这个数字。这样有助在嵌套调用的层次很深时确定程序的位置。注意错误信息通常只回溯到最顶上的4个函数。(当前函数,和它的3个调用者的位置)。所以这并不影响报告的错误总数。最大值是50。注意高的设置会使Valgrind运行得慢,并且使用更多的内存,但是在嵌套调用层次比较高的程序中非常实用。
如果太多错误,则停止显示新错误
指定如果Valgrind在运行过程中报告任何错误时的退出返回值,有两种情况;当设置为默认值(零)时,Valgrind返回的值将是它模拟运行的程序的返回值。当设置为非零值时,如果Valgrind发现任何错误时则返回这个值。
默认地,错误时的栈回溯不显示main()之下的任何函数。
指定一个额外的文件读取不需要理会的错误;你可以根据需要使用任意多的额外文件。
当设置为yes时,Valgrind将会在每个错误显示之后自动暂停并且打印这一行:----Print suppression ? --- [Return/N/n/Y/y/C/c] ----
当设置为all时,Valgrind会对每一个错误打印一条禁止条目,而不向用户询问。
这个提示的行为和--db-attach选项(见下面)相同。这个选项对C++程序非常有用,它打印出编译器调整过的名字。
当这个选项打开时,Valgrind将会在每次打印错误时暂停并打出一行:
---- Attach to debugger ? ---[Return/N/n/Y/y/C/c] ----
按下回车,或者N、回车,n、回车,Valgrind不会对这个错误启动调试器。按下Y、回车,或者y、回车,Valgrind会启动调试器并设定在程序运行的这个点。当调试结束时,退出,程序会继续运行。在调试器内部尝试继续运行程序,将不会生效。按下C、回车,或者c、回车,Valgrind不会启动一个调试器,并且不会再次询问。
注意:--db-attach=yes与--trace-children=yes有冲突。你不能同时使用它们。Valgrind在这种情况下不能启动。
通过--db-attach指定如何使用调试器。默认的调试器是gdb.%f会用可执行文件的文件名替换,%p会被可执行文件的进程ID替换。
使用--db-attach=yes和--gen-suppressions=yes选项,在发现错误时,Valgrind会停下来去读取键盘输入。默认地,从标准输入读取,所以关闭了标准输入的程序会有问题。这个选项允许你指定一个文件描述符来替代标准输入读取。
栈的最大值。如果栈指针的偏移超过这个数量,Valgrind则会认为程序是切换到了另外一个栈执行。
被检测程序加入–g 编译选项保留调试信息(-g带可调试信息,让valgrind调试输出时指出相应信息的代码所在的行号)
valgrind--log-file=valgrind_log--leak-check=full --show-reachable=yes /opt/apache2/bin/httpd–X
valgrind--leak-check=full --show-reachable=yes --trace-children=yes ./iquery -f../conf/se.conf -s offer_gb?q=vcd –NT cache 0
其中参数:
--log-file=valgrind_log检测报告存入valgrind_log中
--leak-check=full 指的是完全检查内存泄漏
--show-reachable=yes是显示内存泄漏的地点
--trace-children=yes是跟入子进程
-NT 不输出时间统计信息
-cache N 指定cache的大小,取值范围[0,131072]
-X 启动单进程模式,即不会产生任何子进程
"LEAK SUMMARY":这表示下面是内存泄露的信息(造成内存丢失的程序行可以通过查看这一行前面的清单来定位)
"definitely lost":肯定丢失的部分,这种报告必须处理
“possiblylost”:可能丢失的部分,这是由于C/C++语言指针处理的特点造成的,这部分可能不太准确