Valgrind 学习
目录

Valgrind is an instrumentation framework for building dynamic analysis tools.

The Valgrind distribution currently includes six production-quality tools:

  • Memcheck: a memory error detector
  • Helgrind: two thread error detectors
  • Cachegrind: a cache and branch-prediction profiler:
  • Callgrind: a call-graph generating cache and branch-prediction profiler:
  • Massif: a heap profiler:

It also includes three experimental tools

  • a heap/stack/global array overrun detector
  • a second heap profiler that examines how heap blocks are used
  • a SimPoint basic block vector generator

Memcheck

Memcheck can detect many memory-related errors that are common in C and C++ programs and that can lead to crashes and unpredictable behaviour.

使用之前写的排序算法做测试,首先使用-g参数编译代码,并推荐-O0-O1参数,减少编译器优化。

gcc -Wall -g -O0 main.c quicksort.c mergesort.c -o sort

然后测试程序:

./sort < input.data
0 1 2 3 4 5 6 7 8 9  => 0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0  => 0 1 2 3 4 5 6 7 8 9
0 0 0 0 0 0 0 0 0 0  => 0 0 0 0 0 0 0 0 0 0
1 1 3 3 3 2 0 0 0 2  => 0 0 0 1 1 2 2 3 3 3
1  => 1
1 0  => 0 1
2 1 0  => 0 1 2
2 3 4 1  => 1 2 3 4
3 2 3 4 5  => 2 3 3 4 5
1 2 1 1 4 3  => 1 1 1 2 3 4
1 0 9 7 9 5 3  => 0 1 3 5 7 9 9
1 9 8 7 6 5 3 9  => 1 3 5 6 7 8 9 9
1 3 9 2 3 4 5 5 4  => 1 2 3 3 4 4 5 5 9

下面使用Valgrind来测试,其中Memcheck就是默认的工具。 The --leak-check option turns on the detailed memory leak detector. 这样输出的结果就是详细内存使用和泄露情况。

valgrind --leak-check=yes ./sort < input.data
==965== Memcheck, a memory error detector
==965== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==965== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==965== Command: ./sort
==965==
0 1 2 3 4 5 6 7 8 9  => 0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0  => 0 1 2 3 4 5 6 7 8 9
0 0 0 0 0 0 0 0 0 0  => 0 0 0 0 0 0 0 0 0 0
1 1 3 3 3 2 0 0 0 2  => 0 0 0 1 1 2 2 3 3 3
1  => 1
1 0  => 0 1
2 1 0  => 0 1 2
2 3 4 1  => 1 2 3 4
3 2 3 4 5  => 2 3 3 4 5
1 2 1 1 4 3  => 1 1 1 2 3 4
1 0 9 7 9 5 3  => 0 1 3 5 7 9 9
1 9 8 7 6 5 3 9  => 1 3 5 6 7 8 9 9
1 3 9 2 3 4 5 5 4  => 1 2 3 3 4 4 5 5 9
==965==
==965== HEAP SUMMARY:
==965==     in use at exit: 0 bytes in 0 blocks
==965==   total heap usage: 26 allocs, 26 frees, 680 bytes allocated
==965==
==965== All heap blocks were freed -- no leaks are possible
==965==
==965== For counts of detected and suppressed errors, rerun with: -v
==965== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

进程ID为965。 在HEAP总结中可以看到,在堆区上共使用了26次内存分配和26次内存释放,没有泄露。 修改下程序,注释一个free语句。编译后重新执行:

...
==1041== HEAP SUMMARY:
==1041==     in use at exit: 680 bytes in 26 blocks
==1041==   total heap usage: 26 allocs, 0 frees, 680 bytes allocated
==1041==
==1041== 340 bytes in 13 blocks are definitely lost in loss record 1 of 2
==1041==    at 0x4C2C04B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1041==    by 0x400792: main (main.c:33)
==1041==
==1041== 340 bytes in 13 blocks are definitely lost in loss record 2 of 2
==1041==    at 0x4C2C04B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1041==    by 0x400BB7: mergesort (mergesort.c:42)
==1041==    by 0x40072E: test_sort (main.c:19)
==1041==    by 0x4007E2: main (main.c:39)
==1041==
==1041== LEAK SUMMARY:
==1041==    definitely lost: 680 bytes in 26 blocks
==1041==    indirectly lost: 0 bytes in 0 blocks
==1041==      possibly lost: 0 bytes in 0 blocks
==1041==    still reachable: 0 bytes in 0 blocks
==1041==         suppressed: 0 bytes in 0 blocks
==1041==
==1041== For counts of detected and suppressed errors, rerun with: -v
==1041== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)

有26次内存分配,0次释放。其中

  • 13个没释放的内存块由main的33行malloc申请
  • 另外13个没释放的内存块由mergesort的42行malloc申请(已打印出调用栈)。

There are several kinds of leaks; the two most important categories are:

  • "definitely lost": your program is leaking memory -- fix it!
  • "probably lost": your program is leaking memory, unless you're doing funny things with pointers (such as moving them to point to the middle of a heap block).

Memcheck能检测出大部分错误,但是有些也不能。比如,静态分配或栈上的数组越界。

除了valgrind的memcheck之外,其它内存检测工具还有:

  • clang的MemorySanitizer, AddressSanitizer和 LeakSanitizer
  • GCC 4.9的AddressSanitizer(asan),LeakSanirizer(lsan),msan,tsan,ubsan
  • gperftools

发表评论