例項介紹利用valgrind定位記憶體洩漏問題
阿新 • • 發佈:2019-01-08
在前面的文章中, 我們簡單瞭解了valgrind工具的用途以及安裝, 以便大家能進行實際操作。 在本文中, 我們通過例項來看看如何利用valgrind來定位記憶體洩漏問題。 先看程式:
#include <stdio.h>
#include <stdlib.h>
char* getMemory()
{
char *p = (char *)malloc(30);
return p;
}
int main()
{
char *p = getMemory();
p = NULL;
return 0;
}
只要是懂一點C/C++的人, 就很容易看出上述程式有記憶體洩漏, 我們用valgrind工具來檢測下:
[ [email protected] ~/valgrind-3.8.1/bin]# ./valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out
==19226== Memcheck, a memory error detector
==19226== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==19226== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==19226== Command: ./a.out
==19226==
==19226==
==19226== HEAP SUMMARY:
==19226== in use at exit: 30 bytes in 1 blocks
==19226== total heap usage: 1 allocs, 0 frees, 30 bytes allocated
==19226==
==19226== 30 bytes in 1 blocks are definitely lost in loss record 1 of 1
==19226== at 0x4C278FE: malloc (vg_replace_malloc.c:270)
==19226== by 0x4005B5: getMemory() (in /root/valgrind-3.8.1/bin/a.out)
==19226== by 0x4005CC: main (in /root/valgrind-3.8.1/bin/a.out)
==19226==
==19226== LEAK SUMMARY:
==19226== definitely lost: 30 bytes in 1 blocks
==19226== indirectly lost: 0 bytes in 0 blocks
==19226== possibly lost: 0 bytes in 0 blocks
==19226== still reachable: 0 bytes in 0 blocks
==19226== suppressed: 0 bytes in 0 blocks
==19226==
==19226== For counts of detected and suppressed errors, rerun with: -v
==19226== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)
[ [email protected] ~/valgrind-3.8.1/bin]#
我們可以很清楚地看到, 在getMemory呼叫malloc的那裡, 有記憶體洩漏。最左邊的19226表示程序號!
不過, 這樣看著也挺蛋疼的, 如果程式碼過多, 肉眼據不太好分析了, 能不能把記憶體洩漏的程式碼行給找出來呢? 當然能! 回想一下我們之前介紹過得core dump定位到程式碼行的問題, 兩個必要條件是: 編譯時必須有-g引數; 編譯後不能strip. 我們一起再看看:
[[email protected] ~/valgrind-3.8.1/bin]# g++ -g test.cpp
[ [email protected] ~/valgrind-3.8.1/bin]#
[[email protected] ~/valgrind-3.8.1/bin]# ./valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out
==20448== Memcheck, a memory error detector
==20448== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==20448== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==20448== Command: ./a.out
==20448==
==20448==
==20448== HEAP SUMMARY:
==20448== in use at exit: 30 bytes in 1 blocks
==20448== total heap usage: 1 allocs, 0 frees, 30 bytes allocated
==20448==
==20448== 30 bytes in 1 blocks are definitely lost in loss record 1 of 1
==20448== at 0x4C278FE: malloc (vg_replace_malloc.c:270)
==20448== by 0x4005B5: getMemory() (test.cpp:5)
==20448== by 0x4005CC: main (test.cpp:11)
==20448==
==20448== LEAK SUMMARY:
==20448== definitely lost: 30 bytes in 1 blocks
==20448== indirectly lost: 0 bytes in 0 blocks
==20448== possibly lost: 0 bytes in 0 blocks
==20448== still reachable: 0 bytes in 0 blocks
==20448== suppressed: 0 bytes in 0 blocks
==20448==
==20448== For counts of detected and suppressed errors, rerun with: -v
==20448== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)
[[email protected] ~/valgrind-3.8.1/bin]#
好了, 洩漏的程式碼行出來了。 這裡, 我順便說說以往介紹過得addr2line命令, 如果用addr2line -e a.out 0x4005B5, 也是能得出程式碼行的。
fix後的程式碼如下:
#include <stdio.h>
#include <stdlib.h>
char* getMemory()
{
char *p = (char *)malloc(30);
return p;
}
int main()
{
char *p = getMemory();
if(p != NULL)
{
free(p);
p = NULL;
}
return 0;
}
我們再用valgrind工具檢測一下:
[[email protected] ~/valgrind-3.8.1/bin]# g++ -g test.cpp
[[email protected] ~/valgrind-3.8.1/bin]#
[[email protected] ~/valgrind-3.8.1/bin]# ./valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out
==21033== Memcheck, a memory error detector
==21033== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==21033== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==21033== Command: ./a.out
==21033==
==21033==
==21033== HEAP SUMMARY:
==21033== in use at exit: 0 bytes in 0 blocks
==21033== total heap usage: 1 allocs, 1 frees, 30 bytes allocated
==21033==
==21033== All heap blocks were freed -- no leaks are possible
==21033==
==21033== For counts of detected and suppressed errors, rerun with: -v
==21033== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
[[email protected] ~/valgrind-3.8.1/bin]#
可見, 沒有記憶體洩漏了。 爽爽噠