背景:
项目代码中发现运行过程中出现一些异常的内存增加,理论上应该是平稳的,不知道为什么增加,所以想要找一个工具进行监测,但是并没有搜到合适的,网上有资料说使用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