LeakSanitizer doesn't produce report after program exit

767 views Asked by At

I'm compiling with Address Sanitizer, and I'm trying to get leak sanitizer reports, but it is only producing an Address Sanitizer report and not producing a LeakSanitizer report after program exit for some reason.

I'm compiling on Centos 7.9 with G++ 9.3.1, Cmake version 3.16.2.

I'm compiling with

list(APPEND SAN_FLAGS "-fsanitize=address" "-fno-omit-frame-pointer" "-g3")

to enable leak sanitizer (which should be enabled with address sanitizer on Linux according to the docs)

I set

Environment="ASAN_OPTIONS=log_path=/var/log/foo_asan.log:detect_leaks=1"

in the service file, then ran my program with systemd (also on Centos 7.9). Stopping the program with systemctl creates a foo_asan. log file as expected, but the log file only has an AddressSanitizer report, but no LeakSanitizer report. How do I get the Leaksanitizer report?

1

There are 1 answers

3
Employed Russian On

the log file only has an AddressSanitizer report, but no LeakSanitizer report.

By default, AddressSanitizer aborts on error. LeakSanitizer only runs on exit, and since your program doesn't exit, you get no leak report.

Here is an example program which has both a memory leak and a buffer overflow:

#include <malloc.h>

void *alloc(size_t sz) { return malloc(sz); }
void fn(char *p, int n) { p[n] = '\0'; }

int main()
{
  const int sz = 10;
  fn(alloc(sz), sz);

  return 0;
}

If I build it with clang -g -fsanitize=address leaky.c -o leaky and run it with ASAN_OPTIONS=detect_leaks=1, I only get the error report:

=================================================================
==1130841==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000001a at pc 0x5555a7f31f0f bp 0x7ffc86de9420 sp 0x7ffc86de9418
WRITE of size 1 at 0x60200000001a thread T0
    #0 0x5555a7f31f0e in fn /tmp/leaky.c:4:32
    #1 0x5555a7f31f4c in main /tmp/leaky.c:9:3
...
==1130841==ABORTING     <<<=== Note this.

This answer shows how to make the program not abort on errors. When I do that, I get both the AddressSanitizer and the LeakSanitizer reports:

clang -g -fsanitize=address -fsanitize-recover=address leaky.c -o leaky
ASAN_OPTIONS=detect_leaks=1:halt_on_error=0 ./leaky

=================================================================
==1131013==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000001a at pc 0x560f9d467f0f bp 0x7ffef258d2b0 sp 0x7ffef258d2a8
WRITE of size 1 at 0x60200000001a thread T0
    #0 0x560f9d467f0e in fn /tmp/leaky.c:4:32
    #1 0x560f9d467f5c in main /tmp/leaky.c:9:3
...
=================================================================
==1131013==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 10 byte(s) in 1 object(s) allocated from:
    #0 0x560f9d42d14e in __interceptor_malloc (/tmp/leaky+0xa314e) (BuildId: d2d081353c37b4b7a8659b1ac39242cfe6259078)
    #1 0x560f9d467eb4 in alloc /tmp/leaky.c:3:33
    #2 0x560f9d467f4f in main /tmp/leaky.c:9:6
    #3 0x7fbf2cc29209 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

SUMMARY: AddressSanitizer: 10 byte(s) leaked in 1 allocation(s).