众所周知,c/c++语言的内存回收依赖于程序员,并没有python,java之类的自动回收。那么内存是申请释放就是个需要认真对待的问题。因为往往诸如服务器是需要长期运行的,即便轻微的内存泄漏也将可能带来严重问题。而且这种bug还存在着复现周期长,难以定位的问题。
链接器有个选项–wrap,当查找某个符号时,它优先先解析__wrap_symbol, 解析不到才会去解析symbol函数。也就是比如我编译选项加入-Wl,-wrap,malloc。那么链接器会优先将malloc调用链接至你定义的__wrap_malloc函数,-Wl是指定链接器参数的意思。也就是说我有诸如以下代码,就可以监测程序内存申请释放。当然为了讨论问题本质,我们暂且忽略realloc/calloc等函数。
// wrap malloc
void *__real_malloc(size_t);
void __real_free(void *);
void *__wrap_malloc(size_t size)
{
trace("malloc: %d bytes\n", size);
return __real_malloc(size);
}
void __wrap_free(void *ptr)
{
trace("free: addr %p\n", ptr);
return __real_free(ptr);
}
但是问题来了,虽然我知道申请了多少内存,释放了哪块内存还是不够的,我还得知道哪里申请了内存。那么接下来的主角登场。
backtrace函数用于获取当前函数的调用堆栈,返回地址信息存放在buffer中。buffer是一个存放void *型返回地址的二级指针,参数 size 指定buffer中可以保存void* 型