内存泄漏分析工具--Valgrind
0 快速入门指南
0.1 简介
Valgrind是一款用于内存调试、内存泄漏检测以及性能分析的软件开发工具。
Valgrind提供了许多调试和分析工具,这些工具中最受欢迎的称为 Memcheck。它可以检测 C 和 C++ 程序中常见的许多与内存相关的错误,这些错误可能导致崩溃和不可预知的行为。
0.1.1 Linux安装valgrind
- 下载valgrind安装包
下载地址 - 安装
tar -x -j -f valgrind-3.18.1.tar.bz2
cd valgrind-3.18.1/
./configure
make
make install
可参考README文件中的安装步骤。
- 测试valgrind是否工作
valgrind ls -l
0.2 准备你的程序
编译你的程序,加-g以包含调试信息,以便Memcheck的错误消息包含准确的行号。
0.3 在Memcheck下运行你的程序
如果你通常像这样运行程序:
myprog arg1 arg2
使用这个命令:
valgrind --leak-check=yes myprog arg1 arg2
Memcheck是默认工具。该--leak-check选项打开内存泄漏检测器。
你的程序将比正常运行慢得多,并使用更多内存。Memcheck将发布它检测到的内存错误和内存泄漏的信息。
0.4 解释Memcheck的输出
这是一个示例C程序,在一个名为a.c的文件中,存在内存错误和内存泄漏。
#include
void f(void)
{
int* x = malloc(10 * sizeof(int));
x[10] = 0; // problem 1: heap block overrun
} // problem 2: memory leak -- x not freed
int main(void)
{
f();
return 0;
}
检测a.c,输出信息如下:
==2565877== Memcheck, a memory error detector
==2565877== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2565877== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==2565877== Command: ./a.out
==2565877==
==2565877== Invalid write of size 4
==2565877== at 0x4005B4: f (a.c:5)
==2565877== by 0x4005C5: main (a.c:10)
==2565877== Address 0x520b068 is 0 bytes after a block of size 40 alloc'd
==2565877== at 0x4C36001: malloc (vg_replace_malloc.c:381)
==2565877== by 0x4005A7: f (a.c:4)
==2565877== by 0x4005C5: main (a.c:10)
==2565877==
==2565877==
==2565877== HEAP SUMMARY:
==2565877== in use at exit: 40 bytes in 1 blocks
==2565877== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==2565877==
==2565877== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==2565877== at 0x4C36001: malloc (vg_replace_malloc.c:381)
==2565877== by 0x4005A7: f (a.c:4)
==2565877== by 0x4005C5: main (a.c:10)
==2565877==
==2565877== LEAK SUMMARY:
==2565877== definitely lost: 40 bytes in 1 blocks
==2565877== indirectly lost: 0 bytes in 0 blocks
==2565877== possibly lost: 0 bytes in 0 blocks
==2565877== still reachable: 0 bytes in 0 blocks
==2565877== suppressed: 0 bytes in 0 blocks
==2565877==
==2565877== For lists of detected and suppressed errors, rerun with: -s
==2565877== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
根据上述信息得,有两处错误:
- Invalid write of size 4。根据at 0x4005B4: f (a.c:5)可知是a.c的第5行出错。
- 40 bytes in 1 blocks are definitely lost in loss record 1 of 1。根据at 0x4C36001: malloc (vg_replace_malloc.c:381)可知已泄露内存的分配位置(已泄漏的内存是在哪里被分配的)。
2565877是进程ID,通常不重要。
0.5 注意事项
Memcheck并不完美,它偶尔会产生误报,并且有抑制这些错误的机制。但是,它通常在99%的情况下都是正确的。
Memcheck 无法检测您的程序存在的每个内存错误。例如,它无法检测对静态分配或堆栈上的数组的超出范围的读取或写入。