现在的位置: 首页 > 综合 > 正文

Valgrind介绍

2013年10月20日 ⁄ 综合 ⁄ 共 6391字 ⁄ 字号 评论关闭

一、什么是valgrind

valgrind是一款运行在linux下的,用来定位c/c++程序中内存使用方面的错误的工具,包括:内存泄漏、使用未初始化的内存、读/写已释放的内存、读/写内存越界、使用malloc/new/new[]和free/delete/delete[]不匹配,等等。         

      Valgrind是帮助程序员寻找程序里的bug和改进程序性能的工具。程序通过valgrind运行时,valgrind收集各种有用的信息,通过这些信息可以找到程序中潜在的bug和性能瓶颈。

二、valgrind的安装

下载

   http://www.valgrind.org

  下载最新版valgrind-3.3.1.tar.bz2

安装

   解压安装包:tar–jxvfvalgrind3.3.1.tar.bz2
解压后生成目录valgrind-3.3.1

   cd valgrind-3.3.1

   ./configure

   make

   make install

好了,现在已经安装好了valgrind,可以开始了解如何使用它了。

三、valgrind的工具介绍

使用Valgrind的工具包,你可以自动的检测许多内存管理和线程的bug,避免花费太多的时间在bug寻找上,使得你的程序更加稳固
Valgrind支持很多工具:Memcheck,Addrcheck,Cachegrind,Massif,Helgrind和Callgrind等   
在运行Valgrind时,你必须指明想用的工具;

    valgrind默认使用memcheck工具,即默认参数

    --tools=memcheck

memcheck

  这个工具可以用来寻找c、c++程序中内存管理的错误。写c或c++程序时,很多隐藏很深的bug是内存操作上出了问题,而这些在Memcheck面前都无处遁形。 

   Memcheck可以检查出下列几种内存操作上的错误:

读写已经释放的内存
读写内存块越界
使用还未初始化的变量
将无意义的参数传递给系统调用
内存泄漏

Cachegrind

用于检查缓存使用的工具
它模拟CPU中的一级缓存I1,D1和L2二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。
在x86和amd64上,cachegrind通过CPUID自动探测机器的cache配置,所以在多数情况下它不再需要更多的配置信息了。
cache对目前系统的性能有决定性的影响。因此这些信息可以指导程序员调整代码,最大限度的提高程序性能。

Callgrind
Callgrind收集程序运行时的一些数据,函数调用关系等信息,还可以有选择地进行cache模拟。在运行结束时,它会把分析数据写入一个文件。
callgrind_annotate可以把这个文件的内容转化成可读的形式。


Helgrind

用于检测多线程竞争资源的工具
它主要用来检查多线程程序中出现的竞争问题。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。Helgrind实现了名为”Eraser”的竞争检测算法,并做了进一步改进,减少了报告错误的次数。

Massif

堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率
程序开发者通过它可以深入了解程序的内存使用行为,从而对内存使用进行优化。这个功能对C++尤其有用(因为C++有很多隐藏的内存分配和释放)

四、Valgrind使用方法

对被测程序的要求:

   要求用gcc编译时使用-g选项

   例如对test.c程序进行编译:gcc-g -o test test.c

基本用法:

   valgrind[option] exefilearg...

   [option]:参数选项

   exefile:可执行程序

   arg...:程序参数

使用内存检测:

   option参数必须加上--leak-check=yes

   举例:以程序test为例,检查test程序内存错误:

    valgrind--leak-check=yes ./test

详细参数说明见valgrind在线帮助手册http://www.valgrind.org/docs/manual/mc-manual.html

五、Valgrind使用参数

5.1基本选项:这些选项对所有工具都有效

  -h --help
 显示所有选项的帮助,包括内核和选定的工具两者。
 --help-debug
  和--help相同,并且还能显示通常只有Valgrind的开发人员使用的调试选项。
 --version
 显示Valgrind内核的版本号。工具可以有他们自已的版本号。这是一种保证工具只在它们可以运行的内核上工作的一种设置。这样可以减少在工具和内核之间版本兼容性导致奇怪问题的概率。
 -q --quiet
  安静的运行,只打印错误信息。在进行回归测试或者有其它的自动化测试机制时会非常有用。
-v--verbose
显示详细信息。在各个方面显示你的程序的额外信息,例如:共享对象加载,使用的重置,执行引擎和工具的进程,异常行为的警告信息。重复这个标记可以增加详细的级别。
-d    
  调试Valgrind自身发出的信息。通常只有Valgrind开发人员对此感兴趣。重复这个标记可以产生更详细的输出。
--tool=<toolname>[default: memcheck]
  运行toolname指定的Valgrind,例如,Memcheck,Addrcheck,Cachegrind,等等。
--trace-children=<yes|no>[default: no]
  当这个选项打开时,Valgrind会跟踪到子进程中。这经常会导致困惑,而且通常不是你所期望的,所以默认这个选项是关闭的。
--track-fds=<yes|no>[default: no]
  当这个选项打开时,Valgrind会在退出时打印一个打开文件描述符的列表。每个文件描述符都会打印出一个文件是在哪里打开的栈回溯,和任何与文件描述符相关的详细信息比如文件名或socket信息。
--time-stamp=<yes|no>[default: no]
  当这个选项打开时,每条信息之前都有一个从程序开始消逝的时间,用天,小时,分钟,秒和毫秒表示。
--log-fd=<number>[default: 2, stderr]
  指定Valgrind把它所有的消息都输出到一个指定的文件描述符中去。默认值2, 是标准错误输出(stderr)。注意这可能会干扰到客户端自身对stderr的使用,Valgrind的输出与客户程序的输出将穿插在一起输出到stderr。
--log-file=<filename>
  指定Valgrind把它所有的信息输出到指定的文件中。实际上,被创建文件的文件名是由filename、‘.’和进程号连接起来的(即<filename>.<pid>),从而每个进程创建不同的文件。
 --log-file-exactly=<filename>
  类似于--log-file,但是后缀“.pid”不会被添加。如果设置了这个选项,使用Valgrind跟踪多个进程,可能会得到一个乱七八糟的文件。      
--log-file-qualifier=<VAR>
  当和--log-file一起使用时,日志文件名将通过环境变量$VAR来筛选,这对于MPI程序是有益的。
--log-socket=<ip-address:port-number>
  指定Valgrind输出所有的消息到指定的IP,指定的端口。当使用1500端口时,端口有可能被忽略。如果不能建立一个到指定端口的连接,Valgrind将输出写到标准错误(stderr)。这个选项经常和一个Valgrind监听程序一起使用。

5.2 错误相关选项:这些选项适用于所有产生错误的工具,比如Memcheck, 但是Cachegrind不行。

--xml=<yes|no>[default: no]
  当这个选项打开时,输出将是XML格式。只有Memcheck时生效。
--xml-user-comment=<string>
  在XML开头附加用户注释,仅在指定了--xml=yes时生效,否则忽略。
--num-callers=<number>[default: 12]
  默认情况下,Valgrind显示12层函数调用的函数名有助于确定程序的位置。可以通过这个选项来改变这个数字。这样有助在嵌套调用的层次很深时确定程序的位置。注意错误信息通常只回溯到最顶上的4个函数。(当前函数,和它的3个调用者的位置)。所以这并不影响报告的错误总数。最大值是50。注意高的设置会使Valgrind运行得慢,并且使用更多的内存,但是在嵌套调用层次比较高的程序中非常实用。
--error-limit=<yes|no>[default: yes]
  如果太多错误,则停止显示新错误
--error-exitcode=<number>[default: 0]
  指定如果Valgrind在运行过程中报告任何错误时的退出返回值,有两种情况;当设置为默认值(零)时,Valgrind返回的值将是它模拟运行的程序的返回值。当设置为非零值时,如果Valgrind发现任何错误时则返回这个值。
--show-below-main=<yes|no>[default: no]
  默认地,错误时的栈回溯不显示main()之下的任何函数。
--suppressions=<filename>[default:$PREFIX/lib/valgrind/default.supp]
  指定一个额外的文件读取不需要理会的错误;你可以根据需要使用任意多的额外文件。
--gen-suppressions=<yes|no|all>[default: no]
  当设置为yes时,Valgrind将会在每个错误显示之后自动暂停并且打印这一行:----Print suppression ? --- [Return/N/n/Y/y/C/c] ----

  当设置为all时,Valgrind会对每一个错误打印一条禁止条目,而不向用户询问。

  这个提示的行为和--db-attach选项(见下面)相同。这个选项对C++程序非常有用,它打印出编译器调整过的名字。

--db-attach=<yes|no>[default: no]

  当这个选项打开时,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-command=<command>[default: gdb-nw%f %p]
  通过--db-attach指定如何使用调试器。默认的调试器是gdb.%f会用可执行文件的文件名替换,%p会被可执行文件的进程ID替换。
--input-fd=<number>[default: 0, stdin]
  使用--db-attach=yes和--gen-suppressions=yes选项,在发现错误时,Valgrind会停下来去读取键盘输入。默认地,从标准输入读取,所以关闭了标准输入的程序会有问题。这个选项允许你指定一个文件描述符来替代标准输入读取。
--max-stackframe=<number>[default: 2000000]
  栈的最大值。如果栈指针的偏移超过这个数量,Valgrind则会认为程序是切换到了另外一个栈执行。


5.3 Valgrind可以识别的错误及错误提示

malloc/free:in use at exit 内存在退出前没有被释放
Invalidwrite of size 非法写内存:一般为数组越界
Invalidread of size 非法读内存:一般为数组越界
definitelylost/possibly lost/still reachable in loss record内存未释放
Invalidfree() / delete / delete[] 同一指针被多次释放
Sourceand destination overlap 内存重叠(一般是使strncpy,memcpy引起)
Syscallparamcontains uninitialisedbyte 调用系统函数时传入了未初始化的变量
Conditionaljump or move depends on uninitialisedvalue 条件判断时使用了未初始化的变量
Accessnot within mapped region/Stack overflow 栈溢出
Mismatchedfree() / delete / delete [] new--delete malloc--free搭配错误

六、举例:valigrind在isearch3.2测试中的应用

编译程序
  被检测程序加入–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 启动单进程模式,即不会产生任何子进程

阅读valgrind给出的内存泄露的报告

     "LEAK SUMMARY":这表示下面是内存泄露的信息(造成内存丢失的程序行可以通过查看这一行前面的清单来定位)

    "definitely lost":肯定丢失的部分,这种报告必须处理

    “possiblylost”:可能丢失的部分,这是由于C/C++语言指针处理的特点造成的,这部分可能不太准确

完整ppt下载:http://download.csdn.net/search?sort=&q=valgrind&per_page=1

抱歉!评论已关闭.