Bug 256524

Summary: Does FreeBSD 12.2-RELEASE amd64 support -fsanitize=leak?
Product: Base System Reporter: ota
Component: binAssignee: freebsd-toolchain (Nobody) <toolchain>
Status: Closed Not A Bug    
Severity: Affects Only Me CC: dim, lwhsu, pjfloyd
Priority: ---    
Version: 12.2-RELEASE   
Hardware: amd64   
OS: Any   

Description ota 2021-06-10 06:23:34 UTC
Looking at /usr/src/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp, amd64 seems to support while i386 does not for clang10, on 12.2-RELEASE:

  SanitizerMask Res = ToolChain::getSupportedSanitizers();
  Res |= SanitizerKind::Address;
  Res |= SanitizerKind::PointerCompare;
  Res |= SanitizerKind::PointerSubtract;
  Res |= SanitizerKind::Vptr;
  if (IsX86_64 || IsMIPS64) {
    Res |= SanitizerKind::Leak;
    Res |= SanitizerKind::Thread;
  }
  if (IsX86 || IsX86_64) {
    Res |= SanitizerKind::Function;
    Res |= SanitizerKind::SafeStack;   
    Res |= SanitizerKind::Fuzzer;
    Res |= SanitizerKind::FuzzerNoLink;
  }

However, amd64 mach gives me "No such file" error while linking.
amd64% clang++ -fsanitize=leak address_sanitizer.cpp
ld: error: cannot open /usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.lsan-x86_64
.a: No such file or directory
clang++: error: linker command failed with exit code 1 (use -v to see invocation
)

i386 explicitly says it is not supported.
i386% clang++ -fsanitize=leak address_sanitizer.cpp
clang++: error: unsupported option '-fsanitize=leak' for target 'i386-unknown-freebsd13.0'

Given Clang 13 document, https://clang.llvm.org/docs/LeakSanitizer.html, doesn't say FreeBSD is supported, I'm not sure if amd64 case is unsupported or an error.
I only have 12.2 RELEASE for amd64 and cannot experiment other FreeBSD version.

% cat address_sanitizer.cpp
int main()
{
    int *i = new int( 1 );
    *i = 0;
}
Comment 1 Dimitry Andric freebsd_committer 2021-06-10 17:07:01 UTC
Even though the code in contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp appears to imply that LeakSanitizer is supported, the required libraries in compiler-rt do not.

E.g. contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.h has:

// LeakSanitizer relies on some Glibc's internals (e.g. TLS machinery) on Linux.
// Also, LSan doesn't like 32 bit architectures
// because of "small" (4 bytes) pointer size that leads to high false negative
// ratio on large leaks. But we still want to have it for some 32 bit arches
// (e.g. x86), see https://github.com/google/sanitizers/issues/403.
// To enable LeakSanitizer on a new architecture, one needs to implement the
// internal_clone function as well as (probably) adjust the TLS machinery for
// the new architecture inside the sanitizer library.
#if (SANITIZER_LINUX && !SANITIZER_ANDROID || SANITIZER_MAC) && \
    (SANITIZER_WORDSIZE == 64) &&                               \
    (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \
     defined(__powerpc64__))
#define CAN_SANITIZE_LEAKS 1
#elif defined(__i386__) && \
    (SANITIZER_LINUX && !SANITIZER_ANDROID || SANITIZER_MAC)
#define CAN_SANITIZE_LEAKS 1
#elif defined(__arm__) && \
    SANITIZER_LINUX && !SANITIZER_ANDROID
#define CAN_SANITIZE_LEAKS 1
#elif SANITIZER_NETBSD
#define CAN_SANITIZE_LEAKS 1
#else
#define CAN_SANITIZE_LEAKS 0
#endif

Somebody needs to step up and implement the required bits upstream, then we can import it into FreeBSD. But for now, we don't have LeakSanitizer.
Comment 2 Paul Floyd 2021-06-10 20:30:28 UTC
Note also that you should be able to use Valgrind memcheck for this as an alternative.
Comment 3 ota 2021-06-11 04:22:51 UTC
Thanks for clarification.