使用LD_PRELOAD加载malloc free

背景:

        项目代码中发现运行过程中出现一些异常的内存增加,理论上应该是平稳的,不知道为什么增加,所以想要找一个工具进行监测,但是并没有搜到合适的,网上有资料说使用valgrind,但是由于这个工具运行起来拖慢程序太多,所以就不太适用。

希望工具应用场景:

        动态检测内存申请,并输出是哪些位置申请了内存,已经申请的大小,方便排查问题

有知道这种工具的朋友,可以留言告知,万分感谢

    

        不过在查找的过程中,想到是不是可以自己实现一个小的工具来检测这个东西,所以就搜到了预加载的相关内容,关于预加载的详细原理,后续再整理,这里只介绍实现。

        搜先查到的是使用__malloc_hook进行处理,但是这个已经不推荐使用了,所以最好使用预加载

代码:

       

  1 #include <iostream>        
  2                            
  3 class testClass
  4 {
  5 public:
  6     testClass() 
  7     {
  8         p = new char[1024];
  9     }
 10     ~testClass() 
 11     {
 12         if (!p) 
 13         delete []p;
 14     }
 15 private:
 16     char* p;
 17 };
 18 
 19 
 20 int main()
 21 {   
 22     char* p = (char*)malloc(16);
 23     free(p);
 24     
 25     testClass myObj;
 26     
 27     return 0;
 28 }
  1 #define _GNU_SOURCE        
  2 #include <stdio.h>         
  3 #include <stdlib.h>        
  4 #include <dlfcn.h>
  5 #include <sys/mman.h>      
  6   
  7 static void* (*real_malloc)(size_t) = NULL;
  8   
  9 static void init()
 10 {
 11     real_malloc  = dlsym(RTLD_NEXT, "malloc");
 12     if (!real_malloc) 
 13     {
 15         exit(1);
 16     }
 17     
 18     printf("=====init...\n");
 19 }
 20 
 21 void *malloc(size_t size)
 22 {
 23     if (!real_malloc) {
 24         init();
 25     }
 26     void *ret = real_malloc(size);  
 27     
 28     printf("my malloc success: size:%d, ptr: %p\n", size, ret);
 29     return ret;
 30 }

第一版代码,这个是有错误的代码

gcc -fPIC -shared -o myMalloc.so myMalloc.cpp -ldl

第一个错误出现,因为自己平时是写C++的,所以自然而然将myMalloc定义成cpp,然后编译报错

 然后将myMalloc.cpp改成myMalloc.c,编译通过

原因:

        xxxx

再编译main.cpp代码

g++  -g main.cpp

然后执行

LD_PRELOAD=./myMalloc.so ./a.out

然后执行段错误

$ LD_PRELOAD=./mwrap.so ./test_wrap
Segmentation fault (core dumped)
原因:

        myMalloc.c里面使用到了printf函数,这个函数内部会调用malloc,然后形成一个死循环的递归,所以出错,应该这样

  9 static void init()
 10 {
 11     real_malloc  = dlsym(RTLD_NEXT, "malloc");
 12     if (!real_malloc) 
 13     {
 14         fprintf(stderr, "unable to get malloc symbol!\n");
 15         exit(1);
 16     }
 17     fprintf(stderr, "myMalloc.so: successfully wrapped!\n");
 18 }

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

然后执行OK

猜你喜欢

转载自blog.csdn.net/bocai1215/article/details/129896874