如何定位Valgrind检测到但缺失调试信息的内存泄漏?
Valgrind检测到涉及ld-linux-x86-64.so的内存泄漏定位方案
问题背景
运行自行编译的程序时,Valgrind检测到如下内存泄漏片段:
==80341== HEAP SUMMARY: ==80341== in use at exit: 6,840 bytes in 27 blocks ==80341== total heap usage: 107,314 allocs, 107,287 frees, 103,658,505 bytes allocated ==80341== ==80341== 8 bytes in 1 blocks are definitely lost in loss record 1 of 27 ==80341== at 0x4843223: operator new[](unsigned long) (vg_replace_malloc.c:714) ==80341== by 0x48A5986: _sub_I_65535_0.0 (commandlineflags.h:132) ==80341== by 0x4004EED: call_init (dl-init.c:90) ==80341== by 0x4004EED: call_init (dl-init.c:27) ==80341== by 0x4004FDB: _dl_init (dl-init.c:137) ==80341== by 0x401B2CF: ??? (in /usr/lib/ld-linux-x86-64.so.2) ==80341== by 0x8: ??? ==80341== by 0x1FFF0000C2: ??? ==80341== by 0x1FFF0000D8: ??? ==80341== by 0x1FFF0000DF: ??? ==80341== by 0x1FFF000126: ??? ==80341== by 0x1FFF00012E: ??? ==80341== by 0x1FFF000147: ??? ==80341== ... ==80341== LEAK SUMMARY: ==80341== definitely lost: 8 bytes in 1 blocks ==80341== indirectly lost: 0 bytes in 0 blocks ==80341== possibly lost: 0 bytes in 0 blocks ==80341== still reachable: 6,832 bytes in 26 blocks ==80341== suppressed: 0 bytes in 0 blocks
泄漏来源判断
这个8字节的definitely lost泄漏大概率来自你的程序,而非Valgrind本身。你提到运行普通程序时Valgrind输出正常,说明Valgrind本身无异常;调用栈中_sub_I_65535_0.0 (commandlineflags.h:132)是关键线索——_sub_I_前缀是编译器生成的静态构造函数入口,说明泄漏发生在全局/静态对象的初始化阶段,和你的代码(或依赖库的初始化逻辑)直接相关。
调试定位步骤
- 检查
commandlineflags.h第132行及周边代码:查看是否存在用new[]分配内存但未对应调用delete[]的全局/静态变量,比如静态数组创建后未在程序退出时释放。 - 安装系统库调试符号:给
ld-linux-x86-64.so所在的glibc安装调试包,Debian/Ubuntu系执行sudo apt install libc6-dbg,RHEL/CentOS系执行sudo dnf install glibc-debuginfo,这样Valgrind能输出完整调用栈,明确初始化过程中的具体调用链路。 - 用GDB跟踪静态初始化:启动GDB后设置断点
break operator new[],当触发该8字节分配时,执行bt查看完整调用栈,确认是哪个全局对象的初始化导致了内存分配。 - 检查第三方库初始化逻辑:如果
commandlineflags.h来自第三方库(如gflags),确认是否需要手动调用库的清理函数(比如gflags的ShutDownCommandLineFlags()),或查看该库是否存在已知的初始化泄漏问题。 - 确保编译时开启调试符号:编译程序时添加
-g选项,让Valgrind能更精准地关联到你的代码行,减少系统库调用栈的干扰。
内容的提问来源于stack exchange,提问作者jerin
相关产品推荐
相关产品推荐

