|
Linux C編程偵測記憶體溢出工具(一):mtrace
|
|
撰/ahliu
前言所有使用動態記憶體分配(dynamic memory allocation)的程式都有機會遇上記憶體溢出(memory leakage)問題,在Linux裡有三種常用工具來偵測記憶體溢出的情況,包括:
- mtrace
- dmalloc
- memwatch
1. mtracemtrace是三款工具之中是最簡單易用的,mtrace是一個C函數,在<mcheck.h>裡宣告及定義,函數原型為: void mtrace(void);
其實mtrace是類似malloc_hook的malloc handler,只不過mtrace的handler function已由系統為你寫好,但既然如此,系統又如何知道你想將malloc/free的記錄寫在哪裡呢?為此,執行mtrace()前要先設定MALLOC_TRACE環境變數: #include <stdlib.h>
....
setenv("MALLOC_TRACE", "output_file_name", 1);
...
「output_file_name」就是儲存偵測結果檔案名稱。 但是偵測結果的格式是一般人無法理解的,而只要有安裝mtrace的話,就會有一名為mtrace的Perl script,在shell輸入以下指令: mtrace [binary] output_file_name
就會將output_file_name的內容轉化成能被理解的語句,例如「No memory leaks」,「0x12345678 Free 10 was never alloc」諸如此類。 例如以下有一程式:(暫且放下single entry single exit的原則) #include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <mcheck.h>
int main() {
char *hello;
setenv("MALLOC_TRACE", "output", 1);
mtrace();
if ((hello = (char *) malloc(sizeof(char))) == NULL) {
perror("Cannot allocate memory.");
return -1;
}
return 0;
}
執行後,再用mtrace 將結果輸出: - 0x08049670 Free 3 was never alloc'd 0x42029acc
- 0x080496f0 Free 4 was never alloc'd 0x420dc9e9
- 0x08049708 Free 5 was never alloc'd 0x420dc9f1
- 0x08049628 Free 6 was never alloc'd 0x42113a22
- 0x08049640 Free 7 was never alloc'd 0x42113a52
- 0x08049658 Free 8 was never alloc'd 0x42113a96
Memory not freed:
-----------------
Address Size Caller
0x08049a90 0x1 at 0x80483fe
最後一行標明有一個大小為1 byte的記憶體尚未釋放,大概是指「hello」吧。 若我們把該段記憶體釋放:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <mcheck.h>
int main() {
char *hello;
setenv("MALLOC_TRACE", "output", 1);
mtrace();
if ((hello = (char *) malloc(sizeof(char))) == NULL) {
perror("Cannot allocate memory.");
return -1;
}
free(hello);
return 0;
}
結果如下: - 0x080496b0 Free 4 was never alloc'd 0x42029acc
- 0x08049730 Free 5 was never alloc'd 0x420dc9e9
- 0x08049748 Free 6 was never alloc'd 0x420dc9f1
- 0x08049668 Free 7 was never alloc'd 0x42113a22
- 0x08049680 Free 8 was never alloc'd 0x42113a52
- 0x08049698 Free 9 was never alloc'd 0x42113a96
No memory leaks.
mtrace的原理是記錄每一對malloc-free的執行,若每一個malloc都有相應的free,則代表沒有記憶體溢出,對於任何非malloc/free情況下所發生的記憶體溢出問題,mtrace並不能找出來。
發表日期:2004-06-23
|
|
|