用户态的内存泄漏定位,函数重载

1、函数重载的方法

如何实现函数打桩_sydyh43的博客-CSDN博客

2、具体实现

代码工程中,申请和释放内存是通过malloc和free实现的。接下来的工作就是对malloc和free两个函数实现重载。在malloc重载函数中创建一个文件,文件名由malloc返回的地址命名,文件中保存调用malloc重载函数的地址。在free重载函数中删除以释放地址命名的文件。运行一段时间后,查看剩余的文件,剩余文件就是可能出现内存泄漏的地址,通过保存在文件中的数据确认调用malloc的地方。

2.1、malloc函数的重载

void *malloc(size_t size)
{
	void *p = NULL;
	void *caller = NULL;
	char buf[MEM_CONTENT_LENGTH] = {0x00};
	FILE *fp = NULL;
	Dl_info info;
	
	if (malloc_stub_enable) {    //malloc_stub_enable解决嵌套问题,因为printf也会调用malloc
		malloc_stub_enable = 0;
		p = malloc_f(size);
        //获取调用malloc函数那一层的地址,由编译器决定
		caller = __builtin_return_address(0);
		memset(&info, 0x00, sizeof(Dl_info));
		(void)dladdr((void*)caller, &info);

		sprintf(buf, "./tmp/%p.mem", p);
        //以函数返回值命名文件
		fp = fopen(buf, "w");
        //存放调用malloc函数的地址
		fprintf(fp, "[+%p]malloc --> caller: %s, addr: %p, size: %lu\n", caller, info.dli_sname, p, size);
		fflush(fp);
		malloc_stub_enable = 1;
		
		return p;
	} else {
		return malloc_f(size);
	}
}

2.2、free函数的重载

void free(void *p)
{
	char buf[MEM_CONTENT_LENGTH] = {0x00};
	
	if (free_stub_enable) {
		free_stub_enable = 0;
		
		sprintf(buf, "./tmp/%p.mem", p);
		//unlink删除文件
		if (unlink(buf) < 0) {
			printf("double free: %p\n", p);
		}
		
		free_stub_enable = 1;
	}
	
	free_f(p);
}

2.3、运行一段时间后获取数据文件

2.3.1、工程本身函数出现的内存泄漏

该地址是程序运行时候的地址,需要减去程序本身的基地址。基地址通过cat /proc/$pid/maps查看

解析地址:addr2line -fe ./malloc_main -a 0xd0a

 2.3.2、动态库中出现的内存泄漏

获取动态库加载时候的基地址

 2.3.3、静态库中出现的内存泄漏。静态库的函数已经编译到调用的函数中,不存在于静态库中

 

3、测试demo源码

 GitHub - dyh-git/memory_leak: 定位内存泄漏demo程序

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值