Leak Sanitizer输出无效?如何获取自定义代码的内存泄漏调用栈
问题重现
我使用
-fsanitize=address -fno-omit-frame-pointer -g -ggdb -O1编译程序,并用-lasan链接后,LeakSanitizer给出如下输出:==87195==ERROR: LeakSanitizer: detected memory leaks Direct leak of 71895 byte(s) in 582 object(s) allocated from: #0 0x7fe4cf8defef in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 #1 0x7fe4cea6c948 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5f948) (BuildId: 88d7a1c8d79fc1becb2737be566dd98523394d55) Direct leak of 6656 byte(s) in 26 object(s) allocated from: #0 0x7fe4cf8defef in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 #1 0x7fe4ce730a01 (/lib/x86_64-linux-gnu/libfontconfig.so.1+0x20a01) (BuildId: 68b386df3452bdfc273639549ced62f4284745b9)输出仅显示系统库的分配调用,看不到自己代码中的函数和行号。已尝试gcc(Ubuntu 12.3.0-1ubuntu1~23.04)、clang(Ubuntu 15.0.7),设置
llvm-symbolizer路径为llvm-symbolizer-15,使用libasan.so.8。
排查步骤与解决方法
确保编译全程保留符号信息
所有自定义代码(包括子模块、本地依赖)的编译命令必须添加-g/-ggdb,且不能使用-s(剥离符号)选项。检查Makefile/CMake配置,确认所有编译目标都包含调试符号参数,预编译的无符号依赖会截断栈帧回溯。调整ASAN栈解析配置
运行程序前设置环境变量,强制精确栈展开并增加捕获深度:export ASAN_OPTIONS=detect_leaks=1:symbolize=1:fast_unwind_on_malloc=0:malloc_context_size=20fast_unwind_on_malloc=0:禁用快速栈展开,改用精确遍历,避免丢失自定义代码层malloc_context_size=20:增大栈帧捕获深度,确保覆盖你的代码调用链symbolize=1:强制启用符号解析
验证符号工具可用性
明确指定llvm-symbolizer路径,确保ASAN能调用到匹配版本的工具:export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-15手动测试工具能否解析你的可执行文件:
llvm-symbolizer-15 -e ./your_program 0x<你的代码地址>若无法输出函数名和行号,重新安装对应版本的llvm-symbolizer,确保与编译器版本兼容。
安装系统库调试符号
系统库缺失调试符号可能干扰栈帧回溯,安装相关调试包:sudo apt-get install libglib2.0-0-dbg libfontconfig1-dbg libc6-dbg完整的系统符号能帮助ASAN更准确回溯栈链,避免在系统库处截断。
切换编译器并统一驱动
若GCC无效,切换到Clang编译时,直接用Clang驱动完成链接,避免ASAN库不兼容:clang -fsanitize=address -fno-omit-frame-pointer -g -O1 your_code.c -o your_programClang的ASAN实现在符号解析上有时更稳定,配合llvm-symbolizer效果更好。
手动解析栈帧
若以上方法无效,手动提取栈地址解析:- 增大
malloc_context_size后,从ASAN输出中找到自定义代码对应的栈地址 - 用
addr2line解析:
或用llvm-symbolizer:addr2line -e ./your_program -f -C <栈地址>llvm-symbolizer-15 -e ./your_program <栈地址>
- 增大
内容的提问来源于stack exchange,提问作者jarlub

