Search code examples
caddress-sanitizer

How get output of address sanitizer when emiting SIGINT to halt a loop


When I compile this simple test program I get the obvious leak report from address sanitizer, but when I compile the same program but with a infinite loop, and break it emitting SIGINT I don't get any output.

Checking asm output, the malloc is not optimized away (if this is possible at all)

Is this the expected behavior of address sanitizer? I don't encounter this problem in other developments.

Working example:

#include <stdlib.h>
int main(void)
{
    char *a = malloc(1024);
    return 1;
}

Not working (kill with SIGINT):

#include <stdlib.h>
int main(void)
{
    char *a = malloc(1024);
    for(;;);
    return 1;
}

compile: gcc test.c -o test -fsanitize=address

I encounter this problem in a full programm but I reduced it to this minimal example.


Solution

  • __lsan_do_leak_check() can help you avoid using longjmp in @KamilCuk's answer:

    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <sanitizer/lsan_interface.h>
    
    void handler (int signum) {
       __lsan_do_leak_check();
    }
    
    int main(int argc, char *argv[])
    {
       signal(SIGINT, handler);
       char *a = malloc(1024);
       a=0;
       printf("lost pointer\n");
       for(;;);
       return 1;
    }
    

    Demo:

    clang test.c -fsanitize=address -fno-omit-frame-pointer -g -O0 -o test && ./test
    lost pointer
      C-c C-c
    =================================================================
    ==29365==ERROR: LeakSanitizer: detected memory leaks
    
    Direct leak of 1024 byte(s) in 1 object(s) allocated from:
        #0 0x4c9ca3 in malloc (/home/bjacob/test+0x4c9ca3)
        #1 0x4f9187 in main /home/bjacob/test.c:13:14
        #2 0x7fbc9898409a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)
    
    SUMMARY: AddressSanitizer: 1024 byte(s) leaked in 1 allocation(s).
    

    Note I added a=0 to create a leak.

    I also added a printf. Without that printf, the leak error is not printed. I suspect the compiler optimized-out the use of the variable "a" despite my using the -O0 compiler option.