Search code examples
cgccmemory-leaksaddress-sanitizerguile

Suppress indirect leaks caused by third party libraries


I have this very simple C code calling a scheme script with guile:

/* main.c */
#include <libguile.h>

int main(void)
{
    scm_init_guile();
    scm_c_primitive_load("script.scm");

    SCM func = scm_variable_ref(scm_c_lookup("func"));

    scm_call_0(func);
    return 0;
}

The scheme script:

; script.scm
(define (func)
    (display "Hello from scheme\n")
)

Compiling and running with:

export ASAN_OPTIONS=detect_leaks=1 LSAN_OPTIONS=suppressions=asan.supp
gcc -std=c11 -Wpedantic -Wall `pkg-config --cflags guile-3.0` \
    -fsanitize=address -fno-omit-frame-pointer \
    -o demo main.c `pkg-config --libs guile-3.0`
./demo

I'm able to suppress some of the leaks caused by guile using this suppression file (asan.supp):

leak:iconv_open
leak:libguile

But one of the leaks doesn't provide enough information, the sanitizer output is:

=================================================================
==33333==ERROR: LeakSanitizer: detected memory leaks

Indirect leak of 208 byte(s) in 1 object(s) allocated from:
    #0 0x7ff8a9b8d517 in malloc (/lib/x86_64-linux-gnu/libasan.so.6+0xb0517)
    #1 0x7ff8a97e94f6  (/lib/x86_64-linux-gnu/libc.so.6+0x344f6)

-----------------------------------------------------
Suppressions used:
  count      bytes template
      2      32752 iconv_open
      1         32 libguile
-----------------------------------------------------

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

As you can see, the information about the leak is very generic (malloc and libc), of course I can not put libc in the suppression file since I will not get information about my real leaks.

Is there any way to suppress all "indirect leaks" caused by third party libraries?


Solution

  • Assuming you already use -fno-omit-frame-pointer - which you do - I believe you need to add fast_unwind_on_malloc=0 to your ASAN_OPTIONS (or LSAN_OPTIONS) in some cases. This will be slower but give more complete backtraces.

    For C++ new/delete the FAQ also suggests switching to -shared-libstdc++, which would presumably be faster. That doesn’t seem relevant to you though.