原文出處: http://blog.yam.com/ddy1280/article/3064451
花了一些時間測試除錯,最後發現問題出現在YACC & LEX 裡面
幫助我抓到這些問題的好工具是 mtrace 。mtrace 是一個 GNU C/C++(Linux platform)提供的函式
使用簡單搭配 gcc -g 除錯資訊,可以輕易找到問題點
例:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(int argc, char *argv[])
5 {
6 int *p;
7 int i;
8
9 #ifdef DEBUG
10 setenv("MALLOC_TRACE", "./memleak.log", 1);
11 mtrace();
12 #endif
13
14 p=(int *)malloc(1000);
15 if (p!=NULL)
16 {
17 for (i=0;i<1000;i++)
18 {
19 p[i]=i;
20 }
21 }
22 else
23 printf("malloc fail");
24
25 return 0;
26 }
在這個程式裡malloc了一個空間,卻沒有free掉,我們為了除錯加了下面這段code
9 #ifdef DEBUG
10 setenv("MALLOC_TRACE", "./memleak.log", 1);
11 mtrace();
12 #endif
然後編譯 gcc -g -o aa -DDEBUG aa.c
執行 ./aa 程式,在進行操作後結束,在目錄裡會發現./memleak.log記錄檔,看其內容,
可讀性相當低完全看不出來那裡出現問題
$ cat memleak.log = Start @ ./aa:(mtrace+0xf9)[0x8048401] + 0x8049ab0 0x3e8 @ /lib/tls/libc.so.6:(clearenv+0x7c)[0x42029acc] - 0x8049690 @ /lib/tls/libc.so.6:(tdestroy+0x39)[0x420dc9e9] - 0x8049700 @ /lib/tls/libc.so.6:(tdestroy+0x41)[0x420dc9f1] - 0x8049728 @ /lib/tls/libc.so.6:[0x42113a22] - 0x8049648 @ /lib/tls/libc.so.6:[0x42113a52] - 0x8049660 @ /lib/tls/libc.so.6:[0x42113a96] - 0x8049678 |
這時可使用 /usr/bin/mtrace 這個由Perl 所寫的工具來解析上面的資訊
$ mtrace aa memleak.log - 0x08049690 Free 3 was never alloc'd 0x42029acc - 0x08049700 Free 4 was never alloc'd 0x420dc9e9 - 0x08049728 Free 5 was never alloc'd 0x420dc9f1 - 0x08049648 Free 6 was never alloc'd 0x42113a22 - 0x08049660 Free 7 was never alloc'd 0x42113a52 - 0x08049678 Free 8 was never alloc'd 0x42113a96 Memory not freed: ----------------- Address Size Caller 0x08049ab0 0x3e8 at /home/ddy/test/aa.c:14 |
善用這類的工具,就能使程式更佳的穩定^__^
<<以上程式在 gcc 3.2.2 on Linux platform 測試無誤>>
參考資料:
The GNU C Library's Allocation Debugging
Identifying Memory Leaks in Linux for C++ Programs