自制内存泄漏排查组件

内存泄漏

内存泄漏的核心原因是调用分配与释放时没有符合开闭原则。有分配却没有释放,这自然会使得进程的堆内存会越来越少,直到耗尽。

一个内存泄漏检测工具需要能够精准地定位到泄漏是由代码中的哪一行所引起的。

可以直接使用一些现成的工具进行内存泄漏的排查,比如valgrind、mtrace、ASAN等等。但这些工具往往不适用于在生成环境中实时地检测内存泄漏,而多是用于在发现内存泄漏后进行测试。特别是valgrind和ASAN对性能的影响也比较大,而且不适用于嵌入式系统。

那么,是否可以自己写一些小工具,对mallocfree做一些简单的跟踪,然后可以随时比较直观地查看是否有内存泄漏呢?

跟踪malloc和free

显然,要检测内存泄漏最基本的思路就是对mallocfree的调用情况进行记录,调用malloc返回一个地址时,对该地址增加一条记录,然后对该地址调用free时,则撤销该记录。最后程序正常运行结束后,还保留下来的那些记录就是内存泄漏的证据了。

首先想到的就是加hook。那么为什么不能像死锁检测组件那样,用dlsym直接对mallocfree加钩子呢?

大量的函数如printf等等本身内部存在调用malloc,在我们重写malloc时难以避免会使用这些函数,这可能引起递归调用:

malloc()
	...
	sprintf()
		...
		malloc()
			....

使用宏定义替换

那怎么办呢?可以考虑用宏定义去替换malloc,比如这样:

void* __malloc(size_t size, const char* file, int line) {
   
    /*...*/
    malloc(size);
    /*...*/
}

void __free(void* ptr, const char* file, int line) {
   
    /*...*/
    free(ptr);
    /*...*/
}

#define malloc(size) __malloc(size, __FILE__, __LINE__)
#define free(ptr) __free(ptr, __FILE__, __LINE__)

这样一来在该宏定义之后,调用mallocfree时实际就是调用__malloc__free了。并且因为这两个函数都传入了文件名和调用位置,因此可以很方便地查看出是在哪些位置调用了某个malloc。

修改后的测试代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void* __malloc(size_t size, 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值