Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -164,7 +164,7 @@ set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${PPC64} ${S390X}) set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64}) -set(ALL_LSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64}) +set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64}) set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64}) set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC64} ${MIPS32} ${MIPS64} ${S390X}) Index: lib/lsan/lsan_allocator.cc =================================================================== --- lib/lsan/lsan_allocator.cc +++ lib/lsan/lsan_allocator.cc @@ -28,12 +28,21 @@ struct ChunkMetadata { u8 allocated : 8; // Must be first. ChunkTag tag : 2; +#if SANITIZER_WORDSIZE == 64 uptr requested_size : 54; +#else + uptr requested_size : 32; + uptr padding : 22; +#endif u32 stack_trace_id; }; -#if defined(__mips64) || defined(__aarch64__) +#if defined(__mips64) || defined(__aarch64__) || defined(__i386__) +#if defined(__i386__) +static const uptr kMaxAllowedMallocSize = 1UL << 30; +#else static const uptr kMaxAllowedMallocSize = 4UL << 30; +#endif static const uptr kRegionSizeLog = 20; static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog; typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap; Index: lib/lsan/lsan_common.h =================================================================== --- lib/lsan/lsan_common.h +++ lib/lsan/lsan_common.h @@ -22,9 +22,19 @@ #include "sanitizer_common/sanitizer_stoptheworld.h" #include "sanitizer_common/sanitizer_symbolizer.h" +// LeakSanitizer relies on some Glibc's internals (e.g. TLS machinery) thus +// supported for Linux only. 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 new architecture, one need to implement +// internal_clone function as well as (probably) adjust TLS machinery for +// new architecture inside sanitizer library. #if (SANITIZER_LINUX && !SANITIZER_ANDROID) && (SANITIZER_WORDSIZE == 64) \ && (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__)) #define CAN_SANITIZE_LEAKS 1 +#elif SANITIZER_LINUX && !SANITIZER_ANDROID && defined(__i386__) +#define CAN_SANITIZE_LEAKS 1 #else #define CAN_SANITIZE_LEAKS 0 #endif Index: lib/lsan/lsan_interceptors.cc =================================================================== --- lib/lsan/lsan_interceptors.cc +++ lib/lsan/lsan_interceptors.cc @@ -26,6 +26,8 @@ #include "lsan_common.h" #include "lsan_thread.h" +#include + using namespace __lsan; extern "C" { @@ -161,13 +163,13 @@ return Allocate(stack, size, 1, kAlwaysClearMemory); INTERCEPTOR_ATTRIBUTE -void *operator new(uptr size) { OPERATOR_NEW_BODY; } +void *operator new(size_t size) { OPERATOR_NEW_BODY; } INTERCEPTOR_ATTRIBUTE -void *operator new[](uptr size) { OPERATOR_NEW_BODY; } +void *operator new[](size_t size) { OPERATOR_NEW_BODY; } INTERCEPTOR_ATTRIBUTE -void *operator new(uptr size, std::nothrow_t const&) { OPERATOR_NEW_BODY; } +void *operator new(size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; } INTERCEPTOR_ATTRIBUTE -void *operator new[](uptr size, std::nothrow_t const&) { OPERATOR_NEW_BODY; } +void *operator new[](size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; } #define OPERATOR_DELETE_BODY \ ENSURE_LSAN_INITED; \ Index: lib/sanitizer_common/sanitizer_flags.inc =================================================================== --- lib/sanitizer_common/sanitizer_flags.inc +++ lib/sanitizer_common/sanitizer_flags.inc @@ -62,7 +62,8 @@ COMMON_FLAG( int, verbosity, 0, "Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output).") -COMMON_FLAG(bool, detect_leaks, true, "Enable memory leak detection.") +COMMON_FLAG(bool, detect_leaks, SANITIZER_WORDSIZE == 64, + "Enable memory leak detection.") COMMON_FLAG( bool, leak_check_at_exit, true, "Invoke leak checking in an atexit handler. Has no effect if " Index: lib/sanitizer_common/sanitizer_linux.h =================================================================== --- lib/sanitizer_common/sanitizer_linux.h +++ lib/sanitizer_common/sanitizer_linux.h @@ -48,7 +48,7 @@ #endif void internal_sigdelset(__sanitizer_sigset_t *set, int signum); #if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) \ - || defined(__powerpc64__) || defined(__s390__) + || defined(__powerpc64__) || defined(__s390__) || defined(__i386__) uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, int *parent_tidptr, void *newtls, int *child_tidptr); #endif Index: lib/sanitizer_common/sanitizer_linux.cc =================================================================== --- lib/sanitizer_common/sanitizer_linux.cc +++ lib/sanitizer_common/sanitizer_linux.cc @@ -1175,6 +1175,71 @@ "r0", "r29", "r27", "r28"); return res; } +#elif defined(__i386__) && SANITIZER_LINUX +uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr) { + int res; + if (!fn || !child_stack) + return -EINVAL; + CHECK_EQ(0, (uptr)child_stack % 16); + child_stack = (char *)child_stack - 7 * sizeof(unsigned int); + ((unsigned int *)child_stack)[0] = (uptr)flags; + ((unsigned int *)child_stack)[1] = (uptr)0; + ((unsigned int *)child_stack)[2] = (uptr)fn; + ((unsigned int *)child_stack)[3] = (uptr)arg; + __asm__ __volatile__( + /* %eax = syscall(%eax = SYSCALL(clone), + * %ebx = flags, + * %ecx = child_stack, + * %edx = parent_tidptr, + * %esi = new_tls, + * %edi = child_tidptr) + */ + + /* Obtain flags */ + "movl (%%ecx), %%ebx\n" + /* Do the system call */ + "pushl %%ebx\n" + "pushl %%esi\n" + "pushl %%edi\n" + /* Remember the flag value. */ + "movl %%ebx, (%%ecx)\n" + "int $0x80\n" + "popl %%edi\n" + "popl %%esi\n" + "popl %%ebx\n" + + /* if (%eax != 0) + * return; + */ + + "test %%eax,%%eax\n" + "jnz 1f\n" + + /* terminate the stack frame */ + "xorl %%ebp,%%ebp\n" + /* Call FN. */ + "call *%%ebx\n" +#ifdef PIC + "call here\n" + "here:\n" + "popl %%ebx\n" + "addl $_GLOBAL_OFFSET_TABLE_+[.-here], %%ebx\n" +#endif + /* Call exit */ + "movl %%eax, %%ebx\n" + "movl %2, %%eax\n" + "int $0x80\n" + "1:\n" + : "=a" (res) + : "a"(SYSCALL(clone)), "i"(SYSCALL(exit)), + "c"(child_stack), + "d"(parent_tidptr), + "S"(newtls), + "D"(child_tidptr) + : "memory"); + return res; +} #endif // defined(__x86_64__) && SANITIZER_LINUX #if SANITIZER_ANDROID Index: lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -16,7 +16,7 @@ #if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__) || \ defined(__aarch64__) || defined(__powerpc64__) || \ - defined(__s390__)) + defined(__s390__) || defined(__i386__)) #include "sanitizer_stoptheworld.h" @@ -528,4 +528,4 @@ #endif // SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__) // || defined(__aarch64__) || defined(__powerpc64__) - // || defined(__s390__) + // || defined(__s390__) || defined(__i386__) Index: test/asan/lit.cfg =================================================================== --- test/asan/lit.cfg +++ test/asan/lit.cfg @@ -205,7 +205,7 @@ config.available_features.add('stable-runtime') # Turn on leak detection on 64-bit Linux. -if config.host_os == 'Linux' and config.target_arch == 'x86_64': +if config.host_os == 'Linux' and (config.target_arch == 'x86_64' or config.target_arch == 'i386'): config.available_features.add('leak-detection') # Set LD_LIBRARY_PATH to pick dynamic runtime up properly. Index: test/lsan/TestCases/disabler.cc =================================================================== --- test/lsan/TestCases/disabler.cc +++ test/lsan/TestCases/disabler.cc @@ -1,5 +1,5 @@ // Test for ScopedDisabler. -// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0:use_tls=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_registers=0:use_stacks=0:use_globals=0:use_tls=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t 2>&1 | FileCheck %s Index: test/lsan/TestCases/do_leak_check_override.cc =================================================================== --- test/lsan/TestCases/do_leak_check_override.cc +++ test/lsan/TestCases/do_leak_check_override.cc @@ -1,7 +1,7 @@ // Test for __lsan_do_leak_check(). We test it by making the leak check run // before global destructors, which also tests compatibility with HeapChecker's // "normal" mode (LSan runs in "strict" mode by default). -// RUN: LSAN_BASE="use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t 2>&1 | FileCheck --check-prefix=CHECK-strict %s // RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t foo 2>&1 | FileCheck --check-prefix=CHECK-normal %s Index: test/lsan/TestCases/high_allocator_contention.cc =================================================================== --- test/lsan/TestCases/high_allocator_contention.cc +++ test/lsan/TestCases/high_allocator_contention.cc @@ -1,6 +1,6 @@ // A benchmark that executes malloc/free pairs in parallel. // Usage: ./a.out number_of_threads total_number_of_allocations -// RUN: LSAN_BASE="use_ld_allocations=0" +// RUN: LSAN_BASE="detect_leaks=1:use_ld_allocations=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE %run %t 5 1000000 2>&1 #include Index: test/lsan/TestCases/large_allocation_leak.cc =================================================================== --- test/lsan/TestCases/large_allocation_leak.cc +++ test/lsan/TestCases/large_allocation_leak.cc @@ -1,8 +1,12 @@ // Test that LargeMmapAllocator's chunks aren't reachable via some internal data structure. -// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t 2>&1 | FileCheck %s +// For 32 bit LSan it's pretty likely that large chunks are "reachable" from some +// internal data structures (e.g. Glibc global data). +// UNSUPPORTED: x86 + #include #include #include "sanitizer_common/print_address.h" Index: test/lsan/TestCases/leak_check_at_exit.cc =================================================================== --- test/lsan/TestCases/leak_check_at_exit.cc +++ test/lsan/TestCases/leak_check_at_exit.cc @@ -1,5 +1,5 @@ // Test for the leak_check_at_exit flag. -// RUN: LSAN_BASE="use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-do // RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-do Index: test/lsan/TestCases/link_turned_off.cc =================================================================== --- test/lsan/TestCases/link_turned_off.cc +++ test/lsan/TestCases/link_turned_off.cc @@ -1,5 +1,5 @@ // Test for disabling LSan at link-time. -// RUN: LSAN_BASE="use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE %run %t // RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t foo 2>&1 | FileCheck %s Index: test/lsan/TestCases/pointer_to_self.cc =================================================================== --- test/lsan/TestCases/pointer_to_self.cc +++ test/lsan/TestCases/pointer_to_self.cc @@ -1,6 +1,6 @@ // Regression test: pointers to self should not confuse LSan into thinking the // object is indirectly leaked. Only external pointers count. -// RUN: LSAN_BASE="report_objects=1:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_stacks=0" not %run %t 2>&1 | FileCheck %s Index: test/lsan/TestCases/print_suppressions.cc =================================================================== --- test/lsan/TestCases/print_suppressions.cc +++ test/lsan/TestCases/print_suppressions.cc @@ -1,6 +1,6 @@ // Print matched suppressions only if print_suppressions=1 AND at least one is // matched. Default is print_suppressions=true. -// RUN: LSAN_BASE="use_registers=0:use_stacks=0" +// RUN: LSAN_BASE="detect_leaks=1:use_registers=0:use_stacks=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:print_suppressions=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-dont-print // RUN: LSAN_OPTIONS=$LSAN_BASE %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-dont-print Index: test/lsan/TestCases/recoverable_leak_check.cc =================================================================== --- test/lsan/TestCases/recoverable_leak_check.cc +++ test/lsan/TestCases/recoverable_leak_check.cc @@ -1,5 +1,5 @@ // Test for on-demand leak checking. -// RUN: LSAN_BASE="use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE %run %t foo 2>&1 | FileCheck %s // RUN: LSAN_OPTIONS=$LSAN_BASE %run %t 2>&1 | FileCheck %s Index: test/lsan/TestCases/register_root_region.cc =================================================================== --- test/lsan/TestCases/register_root_region.cc +++ test/lsan/TestCases/register_root_region.cc @@ -1,5 +1,5 @@ // Test for __lsan_(un)register_root_region(). -// RUN: LSAN_BASE="use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE %run %t // RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t foo 2>&1 | FileCheck %s Index: test/lsan/TestCases/stale_stack_leak.cc =================================================================== --- test/lsan/TestCases/stale_stack_leak.cc +++ test/lsan/TestCases/stale_stack_leak.cc @@ -1,5 +1,5 @@ // Test that out-of-scope local variables are ignored by LSan. -// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=1" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_registers=0:use_stacks=1" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t 2>&1 | FileCheck %s // RUN: LSAN_OPTIONS=$LSAN_BASE":exitcode=0" %run %t 2>&1 | FileCheck --check-prefix=CHECK-sanity %s Index: test/lsan/TestCases/suppressions_default.cc =================================================================== --- test/lsan/TestCases/suppressions_default.cc +++ test/lsan/TestCases/suppressions_default.cc @@ -1,4 +1,4 @@ -// RUN: LSAN_BASE="use_registers=0:use_stacks=0" +// RUN: LSAN_BASE="detect_leaks=1:use_registers=0:use_stacks=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t 2>&1 | FileCheck %s Index: test/lsan/TestCases/suppressions_file.cc =================================================================== --- test/lsan/TestCases/suppressions_file.cc +++ test/lsan/TestCases/suppressions_file.cc @@ -1,4 +1,4 @@ -// RUN: LSAN_BASE="use_registers=0:use_stacks=0" +// RUN: LSAN_BASE="detect_leaks=1:use_registers=0:use_stacks=0" // RUN: %clangxx_lsan %s -o %t // RUN: rm -f %t.supp Index: test/lsan/TestCases/use_after_return.cc =================================================================== --- test/lsan/TestCases/use_after_return.cc +++ test/lsan/TestCases/use_after_return.cc @@ -1,6 +1,6 @@ // Test that fake stack (introduced by ASan's use-after-return mode) is included // in the root set. -// RUN: LSAN_BASE="report_objects=1:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_registers=0" // RUN: %clangxx_lsan %s -O2 -o %t // RUN: ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1 LSAN_OPTIONS=$LSAN_BASE:"use_stacks=0" not %run %t 2>&1 | FileCheck %s // RUN: ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1 LSAN_OPTIONS=$LSAN_BASE:"use_stacks=1" %run %t 2>&1 Index: test/lsan/TestCases/use_globals_initialized.cc =================================================================== --- test/lsan/TestCases/use_globals_initialized.cc +++ test/lsan/TestCases/use_globals_initialized.cc @@ -1,5 +1,5 @@ // Test that initialized globals are included in the root set. -// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_globals=0" not %run %t 2>&1 | FileCheck %s // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_globals=1" %run %t 2>&1 Index: test/lsan/TestCases/use_globals_uninitialized.cc =================================================================== --- test/lsan/TestCases/use_globals_uninitialized.cc +++ test/lsan/TestCases/use_globals_uninitialized.cc @@ -1,5 +1,5 @@ // Test that uninitialized globals are included in the root set. -// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_globals=0" not %run %t 2>&1 | FileCheck %s // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_globals=1" %run %t 2>&1 Index: test/lsan/TestCases/use_poisoned_asan.cc =================================================================== --- test/lsan/TestCases/use_poisoned_asan.cc +++ test/lsan/TestCases/use_poisoned_asan.cc @@ -1,6 +1,6 @@ // ASan-poisoned memory should be ignored if use_poisoned is false. // REQUIRES: asan -// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_poisoned=0" not %run %t 2>&1 | FileCheck %s // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_poisoned=1" %run %t 2>&1 Index: test/lsan/TestCases/use_registers.cc =================================================================== --- test/lsan/TestCases/use_registers.cc +++ test/lsan/TestCases/use_registers.cc @@ -1,5 +1,5 @@ // Test that registers of running threads are included in the root set. -// RUN: LSAN_BASE="report_objects=1:use_stacks=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_stacks=0" // RUN: %clangxx_lsan -pthread %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_registers=0" not %run %t 2>&1 | FileCheck %s // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_registers=1" %run %t 2>&1 Index: test/lsan/TestCases/use_stacks.cc =================================================================== --- test/lsan/TestCases/use_stacks.cc +++ test/lsan/TestCases/use_stacks.cc @@ -1,5 +1,5 @@ // Test that stack of main thread is included in the root set. -// RUN: LSAN_BASE="report_objects=1:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_stacks=0" not %run %t 2>&1 | FileCheck %s // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_stacks=1" %run %t 2>&1 Index: test/lsan/TestCases/use_stacks_threaded.cc =================================================================== --- test/lsan/TestCases/use_stacks_threaded.cc +++ test/lsan/TestCases/use_stacks_threaded.cc @@ -1,5 +1,5 @@ // Test that stacks of non-main threads are included in the root set. -// RUN: LSAN_BASE="report_objects=1:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_registers=0" // RUN: %clangxx_lsan -pthread %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_stacks=0" not %run %t 2>&1 | FileCheck %s // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_stacks=1" %run %t 2>&1 Index: test/lsan/TestCases/use_tls_dynamic.cc =================================================================== --- test/lsan/TestCases/use_tls_dynamic.cc +++ test/lsan/TestCases/use_tls_dynamic.cc @@ -1,5 +1,5 @@ // Test that dynamically allocated TLS space is included in the root set. -// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0:use_ld_allocations=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_stacks=0:use_registers=0:use_ld_allocations=0" // RUN: %clangxx %s -DBUILD_DSO -fPIC -shared -o %t-so.so // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=0" not %run %t 2>&1 | FileCheck %s Index: test/lsan/TestCases/use_tls_pthread_specific_dynamic.cc =================================================================== --- test/lsan/TestCases/use_tls_pthread_specific_dynamic.cc +++ test/lsan/TestCases/use_tls_pthread_specific_dynamic.cc @@ -1,5 +1,5 @@ // Test that dynamically allocated thread-specific storage is included in the root set. -// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=0" not %run %t 2>&1 | FileCheck %s // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=1" %run %t 2>&1 Index: test/lsan/TestCases/use_tls_pthread_specific_static.cc =================================================================== --- test/lsan/TestCases/use_tls_pthread_specific_static.cc +++ test/lsan/TestCases/use_tls_pthread_specific_static.cc @@ -1,5 +1,5 @@ // Test that statically allocated thread-specific storage is included in the root set. -// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=0" not %run %t 2>&1 | FileCheck %s // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=1" %run %t 2>&1 Index: test/lsan/TestCases/use_tls_static.cc =================================================================== --- test/lsan/TestCases/use_tls_static.cc +++ test/lsan/TestCases/use_tls_static.cc @@ -1,5 +1,5 @@ // Test that statically allocated TLS space is included in the root set. -// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=0" not %run %t 2>&1 | FileCheck %s // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=1" %run %t 2>&1 Index: test/lsan/TestCases/use_unaligned.cc =================================================================== --- test/lsan/TestCases/use_unaligned.cc +++ test/lsan/TestCases/use_unaligned.cc @@ -1,5 +1,5 @@ // Test that unaligned pointers are detected correctly. -// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0" +// RUN: LSAN_BASE="detect_leaks=1:report_objects=1:use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_unaligned=0" not %run %t 2>&1 | FileCheck %s // RUN: LSAN_OPTIONS=$LSAN_BASE:"use_unaligned=1" %run %t 2>&1 Index: test/sanitizer_common/TestCases/Posix/sanitizer_set_death_callback_test.cc =================================================================== --- test/sanitizer_common/TestCases/Posix/sanitizer_set_death_callback_test.cc +++ test/sanitizer_common/TestCases/Posix/sanitizer_set_death_callback_test.cc @@ -2,6 +2,13 @@ // REQUIRES: stable-runtime +// For standalone LSan on x86 we have a problem: compiler spills the address +// of allocated at line 42 memory thus memory block allocated in Leak() function +// ends up to be classified as reachable despite the fact we zero out 'sink' at +// the last line of main function. The problem doesn't reproduce with ASan because +// quarantine prohibits memory block reuse for different allocations. +// XFAIL: lsan-x86 + #include #include Index: test/sanitizer_common/TestCases/corelimit.cc =================================================================== --- test/sanitizer_common/TestCases/corelimit.cc +++ test/sanitizer_common/TestCases/corelimit.cc @@ -1,5 +1,5 @@ // RUN: %clangxx -O0 %s -o %t && %run %t -// XFAIL: lsan +// UNSUPPORTED: lsan #include #include Index: test/sanitizer_common/lit.common.cfg =================================================================== --- test/sanitizer_common/lit.common.cfg +++ test/sanitizer_common/lit.common.cfg @@ -26,6 +26,9 @@ if config.target_arch not in ['arm', 'armhf', 'aarch64']: config.available_features.add('stable-runtime') +if config.host_os == 'Linux' and config.target_arch == 'i386' and config.tool_name == "lsan": + config.available_features.add("lsan-x86") + if config.host_os == 'Darwin': # On Darwin, we default to `abort_on_error=1`, which would make tests run # much slower. Let's override this and run lit tests with 'abort_on_error=0'. Index: test/sanitizer_common/print_address.h =================================================================== --- test/sanitizer_common/print_address.h +++ test/sanitizer_common/print_address.h @@ -11,6 +11,8 @@ // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not // match to the format used in the diagnotic message. fprintf(stderr, "0x%012lx ", (unsigned long) p); +#elif defined(__i386__) + fprintf(stderr, "0x%8lx ", (unsigned long) p); #elif defined(__mips64) fprintf(stderr, "0x%010lx ", (unsigned long) p); #endif