要生成可调试的valgrind xml报告,必须同时指定--leak-check=full、--show-leak-kinds=all、--num-callers=20和--track-origins=yes四个参数,并确保程序用-g编译且未被strip。

只加 --leak-check=full 还远远不够
很多人以为加了 --leak-check=full 就能拿到“完整报告”,结果发现 XML 里只有 <kind></kind> 和 <what></what>,没有源码路径、行号、调用栈,根本没法定位问题。这是因为 Valgrind 默认只输出极简摘要,关键调试字段是按需开启的。
--xml-file 必须显式指定,否则 XML 不可用
--xml=yes 只是切换输出格式,不等于“自动保存”。漏掉 --xml-file=valgrind.xml,Valgrind 会把 XML 写进 stderr —— 是单行、无换行、无缩进、UTF-8 编码但不可读不可解析的巨长字符串。任何脚本或解析器都大概率失败。
- 文件路径必须有写权限;推荐用绝对路径,比如
--xml-file=/tmp/valgrind-report.xml - 不能只写
--xml=yes或--xml-file=report.xml(相对路径在子进程或容器中容易失效) - 搭配
--log-file没用,--xml-file和--log-file是互斥输出通道
让 XML 真正可调试的四个必要参数
缺一不可。少一个,<stack></stack> 就不带 <file></file>/<line></line>,或者 <origin></origin> 根本不出现,等于白跑。
-
--leak-check=full:启用完整泄漏检查(不是summary或默认的simple) -
--show-leak-kinds=all:确保DefinitelyLost、PossiblyLost、IndirectlyLost全部进入 XML -
--num-callers=20:默认仅 12 层,C++ 模板展开后常被截断;20 层基本覆盖真实调用链 -
--track-origins=yes:对Use of uninitialised value类错误,XML 才会有<origin></origin>节点,否则只报“条件跳转依赖未初始化值”,找不到源头变量
编译环节决定 XML 能不能定位到代码行
即使所有参数都对,如果程序没带调试信息编译,XML 中的 <file></file>、<line></line>、<dir></dir> 字段照样为空。这不是 Valgrind 的错,是二进制里本来就没有这些符号。
- 编译时必须加
-g,禁用-O2或更高优化(-O1通常可接受,但-O2可能内联掉关键帧) - 确认
readelf -S ./your_program | grep debug能看到.debug_*段 - 运行前别删
.debug文件(某些 strip 流程会误删)
最容易被忽略的是:XML 报告里的 <frame> 是从下往上读的,最底一层才是内存分配点;而 <dir></dir> 和 <file></file> 同时存在才代表你能准确定位到源码——这两项缺失,说明要么编译没加 -g,要么漏了 --num-callers 或 --leak-check=full。











