# memory_check **Repository Path**: YinaYan/memory_check ## Basic Information - **Project Name**: memory_check - **Description**: 排查Linux下的内存泄漏。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-08-11 - **Last Updated**: 2026-01-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 一.模块功能 ​ 统计每个线程内存占用情况及每个内存块的地址、大小等详细信息,实现内存泄漏的检查。 # 二.运行环境 ​ 本模块使用arm-himix200-linux-gcc/g++编译,运行于CV500/DV300硬件。 # 三.运行步骤 1. cd build&&./build.sh&&make 2. 登录板端,NFC挂载,将mem_check拷贝到NFC共享目录 3. 板端执行 ./mem_check,每10秒打印一次线程内存占用情况及内存块的地址、大小等详细信息。 4. 板端执行 ./mem_check cmd=1,则打开串口指令 支持的串口指令: a. help,支持指令的功能 b. lmem,列出内存块的地址、大小等详细信息 c. lthm, 列出线程内存占用情况 d. startm,开始内存统计,默认开启 e. stopm, 停止内存统计 f. clearm, 没实现 g. startmo, 监控是否有内存溢出 h. stopmo, 停止监控内存溢出 5. 结果查看 ![](.\demoResult.png) # 四.模块移植 1. 将memcheck文件夹拷贝至自己的代码目录 2. 添加编译链接参数: ``` -Wl,-wrap,malloc -Wl,-wrap,free -Wl,-wrap,realloc -Wl,-wrap,calloc ``` 3. main函数调用开启内存监控的接口: ``` extern void RegMemCmd(); RegMemCmd(); ``` 4. pthread_create新建线程时,设置线程名字(没有设置线程名字时,默认是主程序的名字如sctrl) ``` #include prctl(PR_SET_NAME,"main"); ``` # 五.原理 ## 1.实现原理 ​ 跟踪内存泄漏,GNU链接器就提供了一个好用的方法: ``` –wrap=symbol ``` ​ **函数名为“wrap_symbol”,且称其为包装函数,“symbol”是一个函数名,大致执行过程是这样的:当调用“symbol”函数时,如果“symbol”函数未定义的话就会调用"``__wrap_symbol"函数;"``__real_symbol"也是个相关的函数,当其只声明不定义的话,我们对其的调用将调用真正的“symbol”函数。** ​ 当然,我们还要添加编译链接参数: ``` -Wl,-wrap,symbol ``` ## 2.用例说明 下面以常用的malloc函数为例说明: 1. 定义__wrap_malloc函数 ``` // wrap.c #include #include void* __real_malloc(size_t size); // 只声明不定义__real_malloc void* __wrap_malloc(size_t size) // 定义__wrap_malloc { printf("__wrap_malloc called, size:%zd\n", size); // log输出 return __real_malloc(size); // 通过__real_malloc调用真正的malloc } ``` 2. 下面是测试用例: ``` // test.c #include #include int main() { char *c = (char *)malloc(sizeof(char)); printf("c = %p\n", c); free(c); return 0; } ``` 3. 下面是编译链接过程: ``` gcc -c wrap.c test.c gcc -Wl,--wrap,malloc -o test wrap.o test.o // 链接参数-Wl,--wrap,malloc ``` 4. 运行: ``` ./test ``` 5. 查看结果: ``` __wrap_malloc called, size:1 c = 0x60d010 ``` ​ 从上面的结果中可以看出,测试用例中使用了malloc,首先调用的是__wrap_malloc函数,然后我们就可以在这个函数中添加我们想要的东西了。在内存创建与销毁时,对内存块进行链表跟踪,就可以对线程及内存块的详细信息进行统计了。 # 六.IPC代码开启内存泄漏检查 IPC代码(git@192.168.32.10:ZW_IPC/rootfs.git)带了内存泄漏检测的代码 ``` ipc_code/server/sctrl/已存在以下文件 linux_wrapper.c mem_debug.h mem_debug.cpp mem_hook.cpp os_wrapper.h ``` 按以下步骤开启: 1. ipccode/server/sctrl/CMakeList.txt更改 ``` set (MEM_DEBUG OFF) 改为: set (MEM_DEBUG ON); ``` 2. ipccode\server\sctrl\main.c的main函数增加: ``` extern void RegMemCmd(); RegMemCmd(); ``` 3. RegMemCmd函数里增加定时打印内存统计信息的线程,可参考demo的RegMemCmd。 4. ipccode\server\sctrl\mem_debug.cpp更改 ``` // 默认内存统计不使能,否则会报segmentation fault错误 static bool s_Enable = true; 改为: static bool s_Enable = false; ``` 5. 运行 ``` cd progs/progs-hi3516CV500/bin/ ./sctrl cmd=1 //默认不支持串口指令,带cmd=1参数后支持串口指令 ``` >上述手段只能将内存泄漏缩小到线程,如果线程代码过于复杂,可以用debug_thread_alloc.c去分析线程内的内存泄漏,目前只支持获取内存泄漏的指针和大小,居于此去分析代码