Note how the only external code called is malloc, the if (0) is skipped, foo(&x) is no-op. Hence, the allocated memory should leak.
Expected result: the leak is detected with Leak Sanitizer.
Real result: the leak is not detected with -fsanitize=address (that enables Leak Sanitizer) on my Ubuntu 22.04 machine with either GCC 11, GCC 12 or Clang-15.
Details:
$ gcc-12 a.c
$ valgrind ./a.out # Leak is detected as expected
==4074== Memcheck, a memory error detector
==4074== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4074== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==4074== Command: ./a.out
==4074==
==4074==
==4074== HEAP SUMMARY:
==4074== in use at exit: 10 bytes in 1 blocks
==4074== total heap usage: 1 allocs, 0 frees, 10 bytes allocated
==4074==
==4074== LEAK SUMMARY:
==4074== definitely lost: 10 bytes in 1 blocks
==4074== indirectly lost: 0 bytes in 0 blocks
==4074== possibly lost: 0 bytes in 0 blocks
==4074== still reachable: 0 bytes in 0 blocks
==4074== suppressed: 0 bytes in 0 blocks
==4074== Rerun with --leak-check=full to see details of leaked memory
==4074==
==4074== For lists of detected and suppressed errors, rerun with: -s
==4074== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ gcc-12 -fsanitize=address a.c
$ ./a.out # Leak is not detected!
$ gcc-12 -fsanitize=leak a.c
$ ./a.out # Leak is detected as expected
=================================================================
==4003==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 10 byte(s) in 1 object(s) allocated from:
#0 0x7fd1a7501302 in __interceptor_malloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:75
#1 0x557ab5a2019c in main (/home/yeputons/a.out+0x119c)
#2 0x7fd1a72eed8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: LeakSanitizer: 10 byte(s) leaked in 1 allocation(s).
The same effect happens if I use gcc-11 or clang-15: both -fsanitize=leak and Valgrind find the leaked s, while -fsanitize=address fails to do so.
Note that the if (0) is important for some reason: if I remove it, the leak is detected with -fsanitize=address too. Order of definition of s and n is important as well. Having Ubuntu 22.04 is apparently important: I was unable to reproduce on Godbolt.
However, adding -stdlib=libc++ for Clang resolves the issue. Hence, I assume it's between Leak Sanitizer and libstdc++.
Consider the following C code in
a.c
:Note how the only external code called is
malloc
, theif (0)
is skipped,foo(&x)
is no-op. Hence, the allocated memory should leak.Expected result: the leak is detected with Leak Sanitizer.
Real result: the leak is not detected with
-fsanitize=address
(that enables Leak Sanitizer) on my Ubuntu 22.04 machine with either GCC 11, GCC 12 or Clang-15.Details:
The same effect happens if I use
gcc-11
orclang-15
: both-fsanitize=leak
and Valgrind find the leakeds
, while-fsanitize=address
fails to do so.Note that the
if (0)
is important for some reason: if I remove it, the leak is detected with-fsanitize=address
too. Order of definition ofs
andn
is important as well. Having Ubuntu 22.04 is apparently important: I was unable to reproduce on Godbolt.However, adding
-stdlib=libc++
for Clang resolves the issue. Hence, I assume it's between Leak Sanitizer and libstdc++.