valgrind使用笔记
安装
笔者使用的是ubuntu16.04系统
使用apt安装
# apt install -y valgrind
看一下版本
$ valgrind --version
valgrind-3.11.0
感觉还挺新啊
写个例子呗
足够简单不注释了
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void test_malloc()
{
char *test = (char *)malloc(32);
}
void test_new()
{
int *test = new int(32);
}
int main()
{
printf("Hello World!\n");
while (1)
{
test_malloc();
test_new();
printf("...\n");
sleep(1);
}
return 0;
}
编译命令
/usr/bin/g++ -fdiagnostics-color=always -g /home/liuyuelong/workspace/CppLearn/valgrind/main.cpp -o /home/liuyuelong/workspace/CppLearn/valgrind/main
vscode 自己生成的,我也懒得自己敲编译命令
使用valgrind检测泄漏
#valgrind --leak-check=full --show-reachable=yes --trace-children= yes /home/liuyuelong/workspace/CppLearn/valgrind/main
输出:
$ valgrind --leak-check=full --show-reachable=yes --trace-children=yes /home/liuyuelong/workspace/CppLearn/valgrind/main
==29701== Memcheck, a memory error detector
==29701== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==29701== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==29701== Command: /home/liuyuelong/workspace/CppLearn/valgrind/main
==29701==
Hello World!
...
...
...
...
然后咋办??????
Ctrl+C停止运行时:
==29701==
==29701== Process terminating with default action of signal 2 (SIGINT)
==29701== at 0x5288370: __nanosleep_nocancel (syscall-template.S:84)
==29701== by 0x52882D9: sleep (sleep.c:55)
==29701== by 0x400739: main (main.cpp:24)
==29701==
==29701== HEAP SUMMARY:
==29701== in use at exit: 82,028 bytes in 519 blocks
==29701== total heap usage: 520 allocs, 1 frees, 83,052 bytes allocated
==29701==
==29701== 1,036 bytes in 259 blocks are definitely lost in loss record 1 of 3
==29701== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29701== by 0x400700: test_new() (main.cpp:12)
==29701== by 0x400725: main (main.cpp:22)
==29701==
==29701== 8,288 bytes in 259 blocks are definitely lost in loss record 2 of 3
==29701== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29701== by 0x4006E7: test_malloc() (main.cpp:7)
==29701== by 0x400720: main (main.cpp:21)
==29701==
==29701== 72,704 bytes in 1 blocks are still reachable in loss record 3 of 3
==29701== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29701== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==29701== by 0x40106F9: call_init.part.0 (dl-init.c:72)
==29701== by 0x401080A: call_init (dl-init.c:30)
==29701== by 0x401080A: _dl_init (dl-init.c:120)
==29701== by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==29701==
==29701== LEAK SUMMARY:
==29701== definitely lost: 9,324 bytes in 518 blocks
==29701== indirectly lost: 0 bytes in 0 blocks
==29701== possibly lost: 0 bytes in 0 blocks
==29701== still reachable: 72,704 bytes in 1 blocks
==29701== suppressed: 0 bytes in 0 blocks
==29701==
==29701== For counts of detected and suppressed errors, rerun with: -v
==29701== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
原来停止运行时,可以输出停止运行时开辟的内存空间,懂了懂了。
但是似乎只能定位到函数,有些不美。
对比正常释放
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void test_malloc_error()
{
char *test = (char *)malloc(32);
}
void test_new_error()
{
int *test = new int(32);
}
void test_malloc()
{
char *test = (char *)malloc(32);
free(test);
test = NULL;
}
void test_new()
{
int *test = new int(32);
delete test;
test = nullptr;
}
int main()
{
printf("Hello World!\n");
for (int i = 0; i < 10; i++)
{
test_malloc();
test_malloc_error();
test_new();
test_new_error();
printf("...\n");
sleep(1);
}
return 0;
}
编译命令加上C++11
/usr/bin/g++ -std=c++11 -fdiagnostics-color=always -g /home/liuyuelong/workspace/CppLearn/valgrind/main.cpp -o /home/liuyuelong/workspace/CppLearn/valgrind/main
运行:
#valgrind --leak-check=full --show-reachable=yes --trace-children= yes /home/liuyuelong/workspace/CppLearn/valgrind/main
对比测试:
$ valgrind --leak-check=full --show-reachable=yes --trace-children=yes /home/liuyuelong/workspace/CppLearn/valgrind/main
==17763== Memcheck, a memory error detector
==17763== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==17763== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==17763== Command: /home/liuyuelong/workspace/CppLearn/valgrind/main
==17763==
Hello World!
...
...
...
...
...
...
...
...
...
...
==17763==
==17763== HEAP SUMMARY:
==17763== in use at exit: 73,064 bytes in 21 blocks
==17763== total heap usage: 42 allocs, 21 frees, 74,448 bytes allocated
==17763==
==17763== 40 bytes in 10 blocks are definitely lost in loss record 1 of 3
==17763== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17763== by 0x400790: test_new_error() (main.cpp:14)
==17763== by 0x400830: main (main.cpp:40)
==17763==
==17763== 320 bytes in 10 blocks are definitely lost in loss record 2 of 3
==17763== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17763== by 0x400777: test_malloc_error() (main.cpp:9)
==17763== by 0x400826: main (main.cpp:38)
==17763==
==17763== 72,704 bytes in 1 blocks are still reachable in loss record 3 of 3
==17763== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17763== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==17763== by 0x40106F9: call_init.part.0 (dl-init.c:72)
==17763== by 0x401080A: call_init (dl-init.c:30)
==17763== by 0x401080A: _dl_init (dl-init.c:120)
==17763== by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==17763==
==17763== LEAK SUMMARY:
==17763== definitely lost: 360 bytes in 20 blocks
==17763== indirectly lost: 0 bytes in 0 blocks
==17763== possibly lost: 0 bytes in 0 blocks
==17763== still reachable: 72,704 bytes in 1 blocks
==17763== suppressed: 0 bytes in 0 blocks
==17763==
==17763== For counts of detected and suppressed errors, rerun with: -v
==17763== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
可以可以的,只有没有回收的内存才有错误信息
但是这样搞,在大型项目上日志就是灾难,咋办?