Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False negative LeakSanitizer when using getline from Ubuntu 22.04's libstdc++ when AddressSanitizer is enabled #1757

Open
yeputons opened this issue May 18, 2024 · 0 comments

Comments

@yeputons
Copy link

Consider the following C code in a.c:

#include <stdlib.h>
#include <stdio.h>
void foo(void *arg) {}
int main() {
    char *s = malloc(10);
    size_t n = 10;
    if (0) {
        getline(&s, &n, stdin);
    }
    char x[8] = {};
    foo(&x);
}

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++.

@yeputons yeputons changed the title False negative LeakSanitizer when using getline on Ubuntu 22.04 with AddressSanitizer enabled with all of GCC 11-12, and Clang 15 with libstdc++ False negative LeakSanitizer when using getline on Ubuntu 22.04 with libstdc++ when AddressSanitizer is enabled May 18, 2024
@yeputons yeputons changed the title False negative LeakSanitizer when using getline on Ubuntu 22.04 with libstdc++ when AddressSanitizer is enabled False negative LeakSanitizer when using getline from Ubuntu 22.04's libstdc++ when AddressSanitizer is enabled May 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant