Valgrind检查内存泄露


包括工具

  • Memcheck。这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。这也是本文将重点介绍的部分。
  • Callgrind。它主要用来检查程序中函数调用过程中出现的问题。
  • Cachegrind。它主要用来检查程序中缓存使用出现的问题。
  • Helgrind。它主要用来检查多线程程序中出现的竞争问题。
  • Massif。它主要用来检查程序中堆栈使用中出现的问题。
  • Extension。可以利用core提供的功能,自己编写特定的内存调试工具。

显然,第一个是重中之重.

使用

准备程序

建议加上-g的参数,编译优化选项请选择O0,虽然这会降低程序的执行效率。

示例代码如下:test.c

#include <stdlib.h>

void fun()
{
    int *p = (int *)malloc(10*sizeof(int));
    p[10] = 0;
}

int main()
{
    fun();
    return 0;
}

运行可执行程序

调用Valgrind的通用格式是:

valgrind [valgrind-options] your-prog [your-prog-options] 在本机编译过后,执行:

valgrind ./test

得到的命令结果如下:

==29859== Memcheck, a memory error detector
==29859== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==29859== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==29859== Command: ./test
==29859== 
==29859== Invalid write of size 4
==29859==    at 0x8048438: fun (in /home/xxx/test/test)
==29859==    by 0x804844A: main (in /home/xxx/test/test)
==29859==  Address 0x4204050 is 0 bytes after a block of size 40 alloc'd
==29859==    at 0x40299D8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==29859==    by 0x804842E: fun (in /home/xxx/test/test)
==29859==    by 0x804844A: main (in /home/xxx/test/test)
==29859== 
==29859== 
==29859== HEAP SUMMARY:
==29859==     in use at exit: 40 bytes in 1 blocks
==29859==   total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==29859== 
==29859== LEAK SUMMARY:
==29859==    definitely lost: 40 bytes in 1 blocks
==29859==    indirectly lost: 0 bytes in 0 blocks
==29859==      possibly lost: 0 bytes in 0 blocks
==29859==    still reachable: 0 bytes in 0 blocks
==29859==         suppressed: 0 bytes in 0 blocks
==29859== Rerun with --leak-check=full to see details of leaked memory
==29859== 
==29859== For counts of detected and suppressed errors, rerun with: -v
==29859== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

结果分析

  • 左边显示类似行号的数字(29859)表示的是 Process ID。
  • 最上面表示的是 valgrind 的版本信息。
  • 中间表示 valgrind 通过运行被测试程序,发现的内存问题。通过阅读这些信息,可以发现:这是一个对内存的非法写操作,非法写操作的内存是4 bytes。发生错误时的函数堆栈,以及具体的源代码行号。非法写操作的具体地址空间。
  • 最下面是对发现的内存问题和内存泄露问题的总结。内存泄露的大小(40 bytes)也能够被检测出来。
  • 示例程序显然有两个问题,一是fun函数中动态申请的堆内存没有释放;二是对堆内存的访问越界。这两个问题均被valgrind发现。

其他

learn from developerWorks