Valgrind 是一个用于构建动态分析工具的检测框架。
Valgrind包含了可以自动检测多种内存管理和线程错误的工具,并对程序进行详细的分析。而且,还可以使用Valgrind来构建新工具。
Valgrind是检测内存泄露工具,可检测如下几种内存泄露风险
No. | type |
---|---|
1 | Illegal read / Illegal write errors |
2 | Use of uninitialized values |
3 | Use of uninitialized or unaddressable values in system calls |
4 | Illegal frees |
5 | When a heap block is freed with an inappropriate deallocation function |
6 | Overlapping source and destination blocks |
7 | Fishy argument values |
编译时注意加-g选项
int main()
{
void* p = malloc(1);
free(p);
*(char*)p = '2';
}
==40816== Invalid write of size 1
==40816== at 0x1091D3: main (test.cpp:22)
==40816== Address 0x4ddfc80 is 0 bytes inside a block of size 1 free'd
==40816== at 0x484B27F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==40816== by 0x1091CE: main (test.cpp:21)
==40816== Block was alloc'd at
==40816== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==40816== by 0x1091BE: main (test.cpp:20)
class test
{
public:
int a;
int b;
void* c;
public:
test(/* args */) = default;
~test() = default;
};
int main()
{
test t;
printf("%d, %p\n", t.a, t.c);
}
编译时注意加-g选项
==40576== Conditional jump or move depends on uninitialised value(s)
==40576== at 0x4B0FE85: __vfprintf_internal (vfprintf-internal.c:1516)
==40576== by 0x4AFA79E: printf (printf.c:33)
==40576== by 0x1091DE: main (test.cpp:21)
==40576== Uninitialised value was created by a stack allocation
==40576== at 0x1091A9: main (test.cpp:19)
Use of uninitialized or unaddressable values in system calls
检测系统调用是否已经初始化。如果要读程序提供的buffer,会检测buffer是否addressable以及是否初始化。如果要写程序提供的buffer,会检查buffer是否addressable。
Illegal free
检测是否重复释放内存块,或者指针没有指向内存的起始位置
int main()
{
void* p = malloc(1);
free(p);
free(p);
}
==41017== Invalid free() / delete / delete[] / realloc()
==41017== at 0x484B27F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==41017== by 0x1091DA: main (test.cpp:22)
==41017== Address 0x4ddfc80 is 0 bytes inside a block of size 1 free'd
==41017== at 0x484B27F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==41017== by 0x1091CE: main (test.cpp:21)
==41017== Block was alloc'd at
==41017== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==41017== by 0x1091BE: main (test.cpp:20)
分配函数 | 释放函数 |
---|---|
malloc, calloc, realloc, valloc, memalign | free |
new | delete |
new[] | delete[] |
#define ADDR_ADD(addr, num) ((char*)addr + num)
int main()
{
void* p = malloc(10);
strncpy(ADDR_ADD(p, 1), (const char*)p, 5);
free(p);
}
==41569== Conditional jump or move depends on uninitialised value(s)
==41569== at 0x484F02A: strncpy (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==41569== by 0x1091FE: main (test.cpp:25)
==41798== Argument 'size' of function malloc has a fishy (possibly negative) value: -10
==41798== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==41798== by 0x1091C0: main (test.cpp:25)
分析内存泄露问题建议在终端中输入以下命令,可输出检测log文件
valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --log-file=res.log ./a.out
1--tool=memcheck: (--tool=
2--leak-check=full: (--leak-check=
3-show-leak-kinds=all(--show-leak-kinds=[default:definite, possible]) valgrind有4种泄露类型,这个参数决定显示哪些类型泄露。可以设置多个以逗号相隔,也可以用all表示全部类型,none表示不显示
4--log-file=log(--log-file=
https://valgrind.org/