#内存泄露# #mtrace# mtrace

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是类似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的内存,只能检测出有泄露,但不能定位。

发布了170 篇原创文章 · 获赞 207 · 访问量 459万+

猜你喜欢

转载自blog.csdn.net/xiaoting451292510/article/details/105094202