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

程序退出后LeakSanitizer未生成报告的技术求助

解决LeakSanitizer未生成报告的问题

针对你遇到的情况,可从以下几个方向排查解决:

1. 确保程序正常退出(核心原因)

LeakSanitizer仅在程序正常调用exit()或从main返回时才会执行内存泄漏扫描。systemctl stop默认会先发送SIGTERM信号,若程序未捕获该信号并优雅退出,超时后会被发送SIGKILL强制终止,此时LeakSanitizer无法触发。

解决办法:

  • 修改systemd服务文件,设置更友好的终止信号:
    [Service]
    KillSignal=SIGINT
    TimeoutStopSec=30
    
    (SIGINT通常程序会处理,给程序足够时间完成退出流程)
  • 在程序代码中捕获SIGTERM信号,收到后调用exit()正常退出:
    #include <signal.h>
    #include <stdlib.h>
    
    void handle_sigterm(int sig) {
        exit(0);
    }
    
    int main() {
        signal(SIGTERM, handle_sigterm);
        // 程序逻辑...
    }
    

2. 明确配置LeakSanitizer选项

虽然Linux下ASAN默认启用LeakSanitizer,但可在ASAN_OPTIONS中显式声明关键选项,避免潜在的配置覆盖:

Environment="ASAN_OPTIONS=log_path=/var/log/foo_asan.log:detect_leaks=1:leak_check_at_exit=1"
  • leak_check_at_exit=1强制LeakSanitizer在程序退出时执行泄漏检查。

3. 完善编译链接配置

确保CMake不仅在编译阶段,也在链接阶段添加ASAN选项,避免链接时缺失相关库:

list(APPEND SAN_FLAGS "-fsanitize=address" "-fno-omit-frame-pointer" "-g3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SAN_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SAN_FLAGS}")

(部分版本的GCC需要链接阶段也指定-fsanitize=address才能正确加载LeakSanitizer模块)

4. 手动触发泄漏检查(备选方案)

若程序无法做到正常退出,可在代码中手动触发LeakSanitizer扫描:

#include <sanitizer/lsan_interface.h>
#include <signal.h>

void handle_sigterm(int sig) {
    __lsan_do_leak_check(); // 执行泄漏扫描
    exit(0);
}

int main() {
    signal(SIGTERM, handle_sigterm);
    // 程序逻辑...
}

编译时无需额外选项,只要已启用-fsanitize=address即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:55:22