You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Leak Sanitizer输出无效?如何获取自定义代码的内存泄漏调用栈

解决LeakSanitizer无法显示自定义代码栈帧的问题

问题重现

我使用-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=20
    
    • fast_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_program
    

    Clang的ASAN实现在符号解析上有时更稳定,配合llvm-symbolizer效果更好。

  • 手动解析栈帧
    若以上方法无效,手动提取栈地址解析:

    1. 增大malloc_context_size后,从ASAN输出中找到自定义代码对应的栈地址
    2. 用addr2line解析:
      addr2line -e ./your_program -f -C <栈地址>
      
      或用llvm-symbolizer:
      llvm-symbolizer-15 -e ./your_program <栈地址>
      

内容的提问来源于stack exchange,提问作者jarlub

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:34:55