linux 提供mtrace/muntrace來檢測程序是否有內存泄露。一般來說要檢測哪一段代碼是否有內存泄露,就可以用這一對函數包起來。mtrace每一對malloc-free的執行,若每一個malloc都有相應的free,則代表沒有內存泄露,對於任何非malloc/free情況下所發生的內存泄露問題,mtrace並不能找出來。也就是對於new的內存,只能檢測出有泄露,但不能定位。因此可能不適用於C++
在使用mtrace之前,先要設置一個環境變量“MALLOC_TRACE”來指定mtrace檢測結果的生成文件名。通過此文件就可以看出代碼是否有內存泄露。MALLOC_TRACE可以用export MALLOC_TRACE=xxx來設置,也可以通過setenv設置。
setenv("MALLOC_TRACE","mtrace_test_output",1);
mtrace_test_output就是儲存檢測結果的文件的名稱。但是檢測結果的格式是一般人無法理解的,而只要有安裝mtrace的話,就會有一名爲mtrace的Perl script,在shell輸入以下指令:mtrace [binary] [file] 就會將output_file_name的內容轉化成能被理解的語句。
mtrace mtrace_test mtrace_test_outpute
mtrace/muntrace是一個C函數,在<mcheck.h>裏聲明及定義,函數原型爲:
void mtrace(void);
void muntrace(void);
mtrace
用於開啓內存使用記錄,muntrace
用於取消內存使用記錄。MALLOC_TRACE用於
內存使用情況記錄到一個文件決定。
其實mtrace是類似malloc_hook的 malloc handler,只不過mtrace的handler function已由系統爲你寫好了而已。
下面我們來對mtrace進行一系列測試工作。
內存分配函數:malloc,calloc,realloc,_alloca, new, free, delete請參考:
https://blog.csdn.net/xiaoting451292510/article/details/105094625
#include <iostream>
#include <mcheck.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
class new_delete_test
{
public:
new_delete_test() :
m_member(0x00)
{
printf("contructor\r\n");
}
~new_delete_test() {
printf("detructor\r\n");
}
private:
int m_member;
};
int main()
{
setenv("MALLOC_TRACE","mtrace_test_output",1);
mtrace();
printf("malloc & new\r\n");
void *p_malloc = malloc(100);
void *p_malloc_no_free = malloc(100);
void *p_calloc = calloc(10, 10);
void *p_calloc_no_free = calloc(10, 10);
void *p_realloc = malloc(100);
p_realloc = realloc(p_realloc, 10);
p_realloc = realloc(p_realloc, 50);
p_realloc = realloc(p_realloc, 100);
p_realloc = realloc(p_realloc, 200);
void *p_realloc_no_free = malloc(1);
p_realloc_no_free = realloc(p_realloc, 100);
int *p_new = new int;
int *p_new_no_delete = new int;
int *p_new_array = new int[100];
int *p_new_array_no_delete = new int[100];
new_delete_test *p_new_class = new new_delete_test;
new_delete_test *p_new_class_no_free = new new_delete_test;
new_delete_test *p_new_class_array = new new_delete_test[3];
new_delete_test *p_new_class_array_no_free = new new_delete_test[3];
printf("***********************************************\r\n");
printf("free & delete\r\n");
free(p_malloc);
p_malloc = NULL;
free(p_calloc);
p_calloc = NULL;
free(p_realloc_no_free);
p_realloc_no_free = NULL;
delete p_new;
p_new = NULL;
delete p_new_array;
p_new_array = NULL;
delete p_new_class;
p_new_class = NULL;
delete[] p_new_class_array;
p_new_class_array = NULL;
printf("***********************************************\r\n");
muntrace();
return 0;
}
編譯生成mtrace_test
g++ -Wall -g mtrace_test.cpp -o mtrace_test
運行mtrace_test
./mtrace_test
生成mtrace_test_output文件
運行以下命令
mtrace mtrace_test mtrace_test_output
可以得到內存泄露信息
Memory not freed:
-----------------
Address Size Caller
0x000000000147d3b0 0x400 at 0x7f4ea91dc1d5
0x000000000147d830 0x64 at /home/cll/99_temp/memory_leak/mtrace/mtrace_test.cpp:26
0x000000000147d910 0x64 at /home/cll/99_temp/memory_leak/mtrace/mtrace_test.cpp:28
0x000000000147d980 0x1 at /home/cll/99_temp/memory_leak/mtrace/mtrace_test.cpp:34
0x000000000147dae0 0x4 at 0x7f4ea97f6c75
0x000000000147dca0 0x190 at 0x7f4ea97f6c75
0x000000000147de60 0x4 at 0x7f4ea97f6c75
0x000000000147dea0 0x14 at 0x7f4ea97f6c75
對於任何非malloc/free情況下所發生的內存泄露問題,mtrace並不能找出來。也就是對於new的內存,只能檢測出有泄露,但不能定位。