detect_leaks 对比 leak_check_at_exit?

detect_leaks vs leak_check_at_exit?

我使用 AddressSanitizer 检查我的应用程序的内存泄漏,但我对这两个标志之间的区别感到困惑:detect_leaksleak_check_at_exit

我认为即使 leak_check_at_exit=0 下面的代码也应该报告内存泄漏,因为泄漏已经发生在每个循环期间而不是在主函数之后 returns:

int main() {
    void *mem;
    for(int i=0; i<1000; i++) {
        mem = malloc(1024);
    }
    return 0;
}

使用 detect_leaks=1:leak_check_at_exit=1 程序确实给出了正确的内存泄漏报告:

=================================================================
==73448==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 1024000 byte(s) in 1000 object(s) allocated from:
    #0 0x7f0933f053f8 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc23f8)
    #1 0x42c8c1 in main src/main.cpp:10
    #2 0x7f0931b05ec4 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)

但是 detect_leaks=1:leak_check_at_exit=0 它不会报告任何内存泄漏。在我看来,设置 leak_check_at_exit=0 等同于设置 detect_leaks=0

问题: detect_leaksleak_check_at_exit 有什么区别?

LeakSanitizer 的工作原理是分析程序内存中指向已分配块的指针。分析非常慢,因此仅在执行结束时执行(您也可以通过调用 __lsan_do_leak_check 来 运行)。

当您设置 leak_check_at_exit=0 时,您实际上禁用了 Lsan。您可以在每次循环迭代时手动插入 __lsan_do_leak_check,但这会减慢程序速度,如果您的应用程序有多个线程,也可能无法正常运行。