mtrace定位内存泄漏问题(仅限 GNU glibc 的 Linux)

发布于:2025-08-11 ⋅ 阅读:(14) ⋅ 点赞:(0)

一、mtrace原理

  • 函数拦截机制:mtrace 利用 glibc 的内部机制,对 malloc() / calloc() / realloc() / free() 等内存函数进行 hook,记录每一次分配和释放行为。
  • 日志记录:记录会写入 MALLOC_TRACE 环境变量指定的日志文件中,包含:
    • 分配的地址
    • 大小
    • 操作类型(M: malloc, F: free)
    • 调用栈返回地址(可用 addr2line 还原)

二、mtrace定位内存泄漏问题(以gtest测试框架为例)

1、main.cpp中添加mtrace

gtest默认的main文件要删掉src_code/srcs/API_with_gtest.cpp

#include <gtest/gtest.h>
#include <mcheck.h>  // mtrace 所在头文件

int main(int argc, char** argv) 
{
    // 先设置环境变量(可选)设置生成的log地址
    setenv("MALLOC_TRACE", "./gtest_mtrace.log", 1);

    // 启动内存追踪
    mtrace();

    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();

    muntrace();  // 关闭追踪,写日志
}

2cmake里面添加add_executable(***   main.cpp,编译

注意编译debug版本 set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")

检查mtrace有没有被编进程序 :

  nm ./Api_Test_Tool_ARC_AVM_AutoCalibrate__imageInfo__010 | grep mtrace

3chmod 777  执行程序的目录

chmod 777 /tmp/apitest  保证目录可以被写入

4、执行程序,生成./gtest_mtrace.log

5、用 mtrace 工具分析日志

在 PC 上执行:
mtrace ./Api_Test_Tool ./gtest_mtrace.log

输出:没有free的内存

Memory not freed:

-----------------

           Address     Size     Caller

0x0000000001da5090     0x30  at 0x73fa515c

0x0000000001da5428     0x18  at 0x73fa515c

0x0000000001da5ae0     0x88  at 0x73fa515c

6、用addr2line定位没有解析出来的地址

$ addr2line -e ./ATT/Api_Test_Tool_ARC_AVM_AutoCalibrate__imageInfo__010 0x73fa515c

输出:??:0

🧨 原因 1:地址不属于这个 ELF 的 .text 区段

我们来确认地址 0x73fa515c 是否属于这个 ELF 的 .text 段(即:代码段),如果不在范围内,那说明这个地址来自其他 .so,比如某个算法库。

检查 .text 段地址范围

执行

readelf -Wl ./ATT/Api_Test_Tool_ARC_AVM_AutoCalibrate__imageInfo__010 | grep LOAD

输出:

  LOAD           0x000000 0x00010000 0x00010000 0x100eb8 0x100eb8 R E 0x10000

  LOAD           0x101d90 0x00121d90 0x00121d90 0x008c8 0x00d1c RW  0x10000

程序的 .text 段(可执行代码段)在 虚拟地址范围是:

0x00010000 ~ 0x00010000 + 0x100eb8 ≈ 0x00110eb8

所以这些地址不在可执行程序内

用addressline定位动态库地址参考:Addr2line使用-CSDN博客


    网站公告

    今日签到

    点亮在社区的每一天
    去签到