Linux环境定位C程序内存泄露以及非法访问的方法
来源:互联网 发布:面试测评软件系统 编辑:程序博客网 时间:2024/05/20 06:29
网上有很多例子,这里主要依照工作中的使用来记录一下心得。通过搜索可以搜到mcheck、mtrace、valgrind等等各种方法。这里记录一下:
1 mcheck
具体可以搜《Linux系统下借助mcheck实现c/c++程序的堆内存异常检查》这篇文章,比较详细。我比较喜欢用其中的b、c两种:
b. 在makefile中使用-lmcheck来链接程序。优点:无需在源码中显式调用mcheck,且一定可以保证mcheck先于malloc被调用;缺点:程序需要重新编译。 c. 通过设置环境变量MALLOC_CHECK_实现:export MALLOC_CHECK_=0表示检测到的堆内存异常都被忽略;export MALLOC_CHECK_=1表示检测到异常时,向stderr打印相关信息,程序继续运行;export MALLOC_CHECK_=2表示检测到异常时,程序立即abort。定位堆内存问题时,推荐设置为2,这样可以在异常发生时及时保留最近的现场。优点:无需改代码,亦无需重新编译;缺点:需设置环境变量,无法打印出堆内存一致性状态,只是简单的abort进程。
其中b的方法,在实际应用中发现有时会导致进程大量占用内存,具体原因没有查出。
其中c的方法,需要注意进程不能以守护方式后台运行。
2 warp
具体可以搜索《使用__wrap_malloc查看内存使用》这篇文章。
相关代码:
// wrap.c#include <stdio.h>#include <stdlib.h>void* __real_malloc(size_t size); // 只声明不定义__real_mallocvoid* __wrap_malloc(size_t size) // 定义__wrap_malloc{ printf("__wrap_malloc called, size:%zd\n", size); // log输出 return __real_malloc(size); // 通过__real_malloc调用真正的malloc}
// test.c#include <stdio.h>#include <stdlib.h>int main(){ char* c = (char*)malloc(sizeof(char)); // 调用malloc printf("c = %p\n", c); free(c); // 调用free,防止内存泄漏 return 0;}
gcc -c wrap.c test.cgcc -Wl,--wrap,malloc -o test wrap.o test.o // 链接参数-Wl,--wrap,malloc
3 hook
参看 https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html 。
在实际项目中,用到的C进程是opensaf拉起来的,涉及到.so和多线程。通过编写实验函数,证明hook的方式,.so中以及子线程中也是有效的。
相关代码:
//test.c#include <stdio.h>#include <string.h>#include <pthread.h>#include <malloc.h>#include "test_so.h"/* Prototypes for our hooks. */static void my_init_hook (void);static void *my_malloc_hook (size_t, const void *);static void my_free_hook (void*, const void *);void *old_malloc_hook = NULL;void *old_free_hook = NULL;static voidmy_init (void){ old_malloc_hook = __malloc_hook; old_free_hook = __free_hook; __malloc_hook = my_malloc_hook; __free_hook = my_free_hook;}static void *my_malloc_hook (size_t size, const void *caller){ void *result; /* Restore all old hooks */ __malloc_hook = old_malloc_hook; __free_hook = old_free_hook; /* Call recursively */ result = malloc (size); /* Save underlying hooks */ old_malloc_hook = __malloc_hook; old_free_hook = __free_hook; /* printf might call malloc, so protect it too. */ printf ("malloc (%u) returns %p\n", (unsigned int) size, result); /* Restore our own hooks */ __malloc_hook = my_malloc_hook; __free_hook = my_free_hook; return result;}static voidmy_free_hook (void *ptr, const void *caller){ /* Restore all old hooks */ __malloc_hook = old_malloc_hook; __free_hook = old_free_hook; /* Call recursively */ free (ptr); /* Save underlying hooks */ old_malloc_hook = __malloc_hook; old_free_hook = __free_hook; /* printf might call free, so protect it too. */ printf ("freed pointer %p\n", ptr); /* Restore our own hooks */ __malloc_hook = my_malloc_hook; __free_hook = my_free_hook;}void thread(void){ int *a = malloc(20); printf("thread malloc\n"); free(a); test_so(); return;}int main (){ pthread_t id; pthread_create(&id, NULL, (void*)thread, NULL); my_init(); int *b = malloc(30); free(b); pthread_join(id, NULL); return 0;}
//test_so.hvoid test_sa();
//test_so.c#include <stdio.h>#include <stdlib.h>#include <string.h>#include "test_so.h"void test_so(){ int *p = malloc(100); printf("test so malloc!\n"); free(p); printf("test so free!\n"); return;}
//编译:gcc test_so.c -fPIC -shared -o libtest.sogcc test.c -L. -ltest -lpthread -o test
- Linux环境定位C程序内存泄露以及非法访问的方法
- 一种定位内存泄露的方法(Linux)
- GDB定位内存泄露的方法(Linux)
- 一种定位内存泄露的方法(Linux)
- 一种定位内存泄露的方法(Linux)
- 一种定位内存泄露的方法(Linux)
- 一种定位内存泄露的方法(Linux)
- 一种定位内存泄露的方法(Linux)
- 定位程序内存泄露的位置
- Linux操作系统下如何监测C程序的内存泄露
- Linux系统下如何监测C程序的内存泄露
- Linux下内存统计和内存泄露类问题的定位方法
- Linux下内存统计和内存泄露类问题的定位方法
- BREW程序内存泄露定位
- Linux C程序内存泄露检测
- Linux C程序内存泄露检测
- linux C内存泄露检测实现及内存泄露检测的一般方法
- linux C内存泄露检测实现及内存泄露检测的一般方法
- 嵌入式Linux系统设计--第六章:嵌入式Linux开发入门
- 颜色空间
- Java获取IP地址
- HashMap1.6-源码
- 我将进化成一条狗(12)——完结
- Linux环境定位C程序内存泄露以及非法访问的方法
- nodejs最开始操作
- 计算机组成原理-存储器实验
- ubuntu16.04 cuda8.0 opencv3.1 gtx1080 配置ssd
- 练习39
- 数字电子技术复习(三)——触发器和时序电路
- javascript:typeof与instanceof区别
- maven工程启动eclipse 报错java.lang.NoClassDefFoundError:
- Zookeeper---概念梳理