美文网首页
内存泄漏检测利器:使用LD_PRELOAD加载你的malloc库

内存泄漏检测利器:使用LD_PRELOAD加载你的malloc库

作者: crazyhank | 来源:发表于2021-05-04 08:01 被阅读0次

使用C或者C++开发程序的同学肯定有过类似的经历,当程序发生内存泄漏时,如果运气好,很快能够找到代码出错的地方,但是如果代码庞大,定位起来将是一个非常头疼的问题。
这里我给出一个方法可以帮助你快速定位出内存泄漏的地方,而且这个方法不需要修改你原有的代码。大概的原理如下:
1、使用封装的方式实现你自己的malloc, realloc, free, calloc等内存管理函数。
2、在内存申请封装函数里记录申请的地址以及调用栈(可以使用unwind库)。
3、在内存释放封装函数里先查询该地址是否被记录,如果是则将之前的记录销账掉。
4、使用LD_PRELOAD环境变量提前加载你的封装库,开始运行你的程序。
5、经过一段时间后,如果产生了内存泄漏现象,上面未销账的记录即有可能是内存泄漏点,打印相应的堆栈就可知道出问题的代码。

这里简单演示一下封装malloc函数的示例代码:

  • mwrap.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <sys/mman.h>

static void* (*real_malloc)(size_t)         = NULL;

static void init()
{
    real_malloc  = dlsym(RTLD_NEXT, "malloc");
    if (!real_malloc) {
        fprintf(stderr, "unable to get malloc symbol!\n");
        exit(1);
    }
    fprintf(stderr, "mwrap.so: successfully wrapped!\n");
}

void *malloc(size_t size)
{
    if (!real_malloc) {
        init();
    }
    void *ret = real_malloc(size);
    fprintf(stderr, "using wrapped malloc: size = %ld, pointer = %p\n", size, ret); // 如果打印,一定要用fprintf(stderr),否则会产生无限循环,因为fprintf(stdout)也会使用malloc!

    return ret;
}

$ gcc -fPIC -shared -o mwrap.so mwrap.c -ldl

  • 测试程序:test_wrap.cpp
#include <iostream>

class MyClass {
public:
    MyClass() {p = new char[1024];}
    ~MyClass() {if (!p) delete []p;}
private:
    char* p;
};


int main()
{
    char* p = (char*)malloc(16);
    free(p);

    MyClass myObj;

    return 0;
}

$ g++ -o test_wrap test_wrap.cpp

  • 测试
hank@hank-ThinkPad-T450s:~/cpp/test_preload$ LD_PRELOAD=./mwrap.so ./test_wrap
mwrap.so: successfully wrapped!
using wrapped malloc: size = 72704, pointer = 0x559481454260
using wrapped malloc: size = 16, pointer = 0x559481465e70
using wrapped malloc: size = 1024, pointer = 0x559481465e90

可以看到test_wrap代码中无论是使用new还是直接使用malloc的代码都会调用封装后的malloc库,这时候你就可以在封装的函数里记录你想要的信息了。

相关文章

  • 内存泄漏检测利器:使用LD_PRELOAD加载你的malloc库

    使用C或者C++开发程序的同学肯定有过类似的经历,当程序发生内存泄漏时,如果运气好,很快能够找到代码出错的地方,但...

  • 内存优化

    native内存泄漏检测原理? 有一个apiAPI:get_malloc_leak_info参考:https://...

  • Android中LeakCanary检测内存泄漏

    最近要对产品进行内存泄漏的检查,最后选择了使用Square公司开源的一个检测内存泄漏的函数库LeakCanary,...

  • LeakCanary 源码记录 基于V2.7

    LeakCanery作为Android中检测内存泄漏的利器, 已经被广泛使用了很长时间了, 核心原理也有很多博文细...

  • 内存——库

    库的使用   在使用库(例如libcurl)时,不可避免地会出现内存增长并不可逆的情况,所以在检测内存泄漏时只需检...

  • LeakCanary 源码分析

    LeakCanary是一个检测内存泄漏的工具,使用非常简单。主要用来检测Activity和Fragment内存泄漏...

  • Xcode instruments工具检测内存泄露不显示方法名

    有时候我们为了检测内存泄漏,使用instruments的Leak工具,但是检测到内存泄漏后,显示的都是地址,却没办...

  • LeakCanary原理分析

    概述 LeakCanary是一个开源的内存泄漏检测库,极大简化了内存泄漏的检测流程。了解其工作原理,有助于我们更好...

  • LeakCanary 分析:一只优雅的金丝雀

    LeakCanary 是 Square 公司的一个开源库。通过它可以在 App 运行过程中检测内存泄漏,当内存泄漏...

  • iOS性能优化-内存泄漏

    前言:本文旨在介绍iOS性能优化中有关内存泄漏的介绍和检测。 一、什么是内存泄漏? 内存泄漏是指申请的内存空间使用...

网友评论

      本文标题:内存泄漏检测利器:使用LD_PRELOAD加载你的malloc库

      本文链接:https://www.haomeiwen.com/subject/ntqcdltx.html