- 海之寻趣
- Ranler
- 2014-07-16 09:35
- CC BY-NC-SA
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