valgrind工具使用

Valgrind的最新版是3.2.3,该版本包含下列工具:

1、memcheck:检查程序中的内存问题,如泄漏、越界、非法指针等。

2、callgrind:检测程序代码覆盖,以及分析程序性能。

3、cachegrind:分析CPU的cache命中率、丢失率,用于进行代码优化。

4、helgrind:用于检查多线程程序的竞态条件。

5、massif:堆栈分析器,指示程序中使用了多少堆内存等信息。

6、lackey:

7、nulgrind:

本文使用的是内存检测工具memcheck

memcheck最常用的工具,用来检测程序中出现的内存问题,所有对内存的读写都会被检测到,一切对malloc、free、new、delete的调用都会被捕获。所以,它能检测以下问题:

1、对未初始化内存的使用;

2、读/写释放后的内存块;

3、读/写超出malloc分配的内存块;

4、读/写不适当的栈中内存块;

5、内存泄漏,指向一块内存的指针永远丢失;

6、不正确的malloc/free或new/delete匹配;

7、memcpy()相关函数中的dst和src指针重叠。

这些问题往往是C/C++程序员最头疼的问题,Memcheck能在这里帮上大忙。

 

为了更形象的说明使用方法,在此以一段简短的程序片段为例,说明Valgrind工具检查内存问的方法,具体操作如下:

1. 编写一段有内存泄露和内存越界的代码片段

  • #include <thread>
  • #include <cstring>
  • #include <cstdio>
  • #include <cstdlib>
  • #include <new>
  • #include <thread>
  • #include <cstring>
  •  
  • struct  TEST
  • {
  •     int a;
  •     int b;
  • };
  • void dddfd(int a)
  • {
  •     TEST* p= new dddda23;
  •     memset(p,0,20);
  •     unsigned char* pp        = (unsigned char*)malloc(100*1024*1024);
  • }
  • int main()
  • {
  •     dddfd(1);
  • }

                                                          图1 有内存泄漏的程序片段

2. 运行valgrind工具,给出检测分析报告

valgrind --leak-check=full --show-leak-kinds=all --tool=memcheck ./a.out

检测结果如图2所示,“definitely lost”说明程序肯定存在内存泄露;(“possibly lost”)

说明程序可能存在内存泄露,两处泄漏位置在dddfd()函数,

invalid write of size 4 内存写越界

                                                                       图2 Valgrind检测结果

3. 修改代码,正常释放内存,检测结果正常

  • #include <thread>
  • #include <cstring>
  • #include <cstdio>
  • #include <cstdlib>
  • #include <new>
  • #include <thread>
  • #include <cstring>
  •  
  • struct  TEST
  • {
  •     int a;
  •     int b;
  • };
  • void dddfd(int a)
  • {
  •     TEST* p= new dddda23;
  •     memset(p,0,20);
  •     unsigned char* pp        = (unsigned char*)malloc(100*1024*1024);
  •     free(pp);
  •     delete p;
  • }
  • int main()
  • {
  •     dddfd(1);
  • }

修改后内存检测结果如下图3所示,无内存使用问题:

                                                                 图4 valgrind检测结果

4.Massif是一个内存剖析工具。通过不断的取程序堆的快照来达到监视程序内存分配的目的。

实例代码:

                                                

执行命令 valgrind --tool=massif ./a.out

得到一个massif文件: massif.out.29862 (29862为进程id)

使用ms_print massif.out.29862 解析文件得到如下解析结果: