c/c++ 内存泄漏检测

线上系统发现虚拟内存在不断的涨,出现内存泄露如何解;

1、内存泄露为什么不好处理;

        1)虚拟内存在涨的时候,我们不确定是程序的需要还是内存泄漏;

        2)不知道到底是哪行代码导致内存泄漏;

内存泄漏产生的原因无非是malloc/new和free/delete调用不匹配;

2、如何判断内存泄漏,哪个地方的代码实现导致内存泄漏;内存泄漏检测;

        1)通过mtrace检测内存泄漏;运行代码后通过mem.txt日志查看内存泄漏情况;对于线上系统是需要重启的,如果不重启可以通过热更新,在.conf文件中加入mtrace;

运行上图程序得到mem.txt文件如下,通过+和-的匹配情况判断是否有内存泄漏;

然后通过addr2line命令就可以查看是在哪里出现了内存泄漏;

        2)宏定义检测内存泄漏;

宏定义检测的优缺点:只适合在单文件中使用;

对于线上系统,通过热更新检测;

        3)通过hook方式检测内存泄漏;

typedef void *(*malloc_t)(size_t size);

typedef void (*free_t)(void *ptr);

malloc_t malloc_f = NULL;

free_t free_f = NULL;

int enable_malloc_hook = 1;

int enable_free_hook = 1;

void *malloc(size_t size) {

    if(enable_malloc_hook)

   {

        enable_malloc_hook= 0;

        void *p = malloc_f(size);

        void * caller = __builten_return address(0);

        char buff[128];

       sprintf(buff, "./mem/%p.mem", p);

        FILE *fp = fopen(buff,"w");

        fprintf(fp,"[+]%s :%d, addr: %p,size: %ld\n"FILE_,_LINE__, p,size);

        fflush(fp);

        enable malloc_hook = 1;

    }

    else

    {

        p = malloc_f(size);

    }

    return p;

}

void free(void *ptr) {

    if(enable_free_hook)

    {

        enable_free_hook = 0;

        char buff[128] = (0};

        sprintf(buff,"./mem/%p.mem", p);

        free_f(ptr);

        enable free hook = 1;

    }

}

static void init_hook(void) {

    if (malloc_f == NULL) {

        malloc_f = (malloc_t)dlsym(RTLD_NEXT, "malloc");

    }

    if (free_f == NULL) {

        free_f = (free_t)dlsym(RTLD_NEXT, "free");

    }

}
 

int main() {

    init_hook();

    void *p1 = malloc(10); 

    void *p2 = malloc(15);

    void *p3 = malloc(20);

    free(p2);

    free(p3);

}

        4)__libc_malloc();接口,malloc底层调用的是该接口;思路和hook是一样的;

        5)老版本接口,是被攻击的很重要的点,即__malloc_hook,是一种指针的方式;系统提供了一个指针,每一次调用malloc函数的时候,底层会调用到__malloc_hook指针,这个指针是固定的值;这是linux本身提供的hook的机制;这种方式慎用,因为它已经是已被遗弃的老的接口;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值