Index: test/lsan/TestCases/Linux/lit.local.cfg =================================================================== --- /dev/null +++ test/lsan/TestCases/Linux/lit.local.cfg @@ -0,0 +1,9 @@ +def getRoot(config): + if not config.parent: + return config + return getRoot(config.parent) + +root = getRoot(config) + +if root.host_os not in ['Linux']: + config.unsupported = True Index: test/lsan/TestCases/cleanup_in_tsd_destructor.c =================================================================== --- /dev/null +++ test/lsan/TestCases/cleanup_in_tsd_destructor.c @@ -1,46 +0,0 @@ -// Regression test for thread lifetime tracking. Thread data should be -// considered live during the thread's termination, at least until the -// user-installed TSD destructors have finished running (since they may contain -// additional cleanup tasks). LSan doesn't actually meet that goal 100%, but it -// makes its best effort. -// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0" -// RUN: %clang_lsan %s -o %t -// RUN: LSAN_OPTIONS=$LSAN_BASE:use_tls=1 %run %t -// RUN: LSAN_OPTIONS=$LSAN_BASE:use_tls=0 not %run %t 2>&1 | FileCheck %s - -#include -#include -#include -#include - -#include "sanitizer/lsan_interface.h" -#include "sanitizer_common/print_address.h" - -pthread_key_t key; -__thread void *p; - -void key_destructor(void *arg) { - // Generally this may happen on a different thread. - __lsan_do_leak_check(); -} - -void *thread_func(void *arg) { - p = malloc(1337); - print_address("Test alloc: ", 1, p); - int res = pthread_setspecific(key, (void*)1); - assert(res == 0); - return 0; -} - -int main() { - int res = pthread_key_create(&key, &key_destructor); - assert(res == 0); - pthread_t thread_id; - res = pthread_create(&thread_id, 0, thread_func, 0); - assert(res == 0); - res = pthread_join(thread_id, 0); - assert(res == 0); - return 0; -} -// CHECK: Test alloc: [[ADDR:0x[0-9,a-f]+]] -// CHECK: [[ADDR]] (1337 bytes) Index: test/lsan/TestCases/disabler_in_tsd_destructor.c =================================================================== --- /dev/null +++ test/lsan/TestCases/disabler_in_tsd_destructor.c @@ -1,39 +0,0 @@ -// Regression test. Disabler should not depend on TSD validity. -// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0:use_tls=1:use_ld_allocations=0" -// RUN: %clang_lsan %s -o %t -// RUN: LSAN_OPTIONS=$LSAN_BASE %run %t - -#include -#include -#include -#include - -#include "sanitizer/lsan_interface.h" - -pthread_key_t key; - -void key_destructor(void *arg) { - __lsan_disable(); - void *p = malloc(1337); - // Break optimization. - fprintf(stderr, "Test alloc: %p.\n", p); - pthread_setspecific(key, 0); - __lsan_enable(); -} - -void *thread_func(void *arg) { - int res = pthread_setspecific(key, (void*)1); - assert(res == 0); - return 0; -} - -int main() { - int res = pthread_key_create(&key, &key_destructor); - assert(res == 0); - pthread_t thread_id; - res = pthread_create(&thread_id, 0, thread_func, 0); - assert(res == 0); - res = pthread_join(thread_id, 0); - assert(res == 0); - return 0; -} Index: test/lsan/TestCases/fork.cc =================================================================== --- /dev/null +++ test/lsan/TestCases/fork.cc @@ -1,24 +0,0 @@ -// Test that thread local data is handled correctly after forking without exec(). -// RUN: %clangxx_lsan %s -o %t -// RUN: %run %t 2>&1 - -#include -#include -#include -#include -#include - -__thread void *thread_local_var; - -int main() { - int status = 0; - thread_local_var = malloc(1337); - pid_t pid = fork(); - assert(pid >= 0); - if (pid > 0) { - waitpid(pid, &status, 0); - assert(WIFEXITED(status)); - return WEXITSTATUS(status); - } - return 0; -} Index: test/lsan/TestCases/fork_threaded.cc =================================================================== --- /dev/null +++ test/lsan/TestCases/fork_threaded.cc @@ -1,43 +0,0 @@ -// Test that thread local data is handled correctly after forking without -// exec(). In this test leak checking is initiated from a non-main thread. -// RUN: %clangxx_lsan %s -o %t -// RUN: %run %t 2>&1 - -#include -#include -#include -#include -#include -#include - -__thread void *thread_local_var; - -void *exit_thread_func(void *arg) { - exit(0); -} - -void ExitFromThread() { - pthread_t tid; - int res; - res = pthread_create(&tid, 0, exit_thread_func, 0); - assert(res == 0); - pthread_join(tid, 0); -} - -int main() { - int status = 0; - thread_local_var = malloc(1337); - pid_t pid = fork(); - assert(pid >= 0); - if (pid > 0) { - waitpid(pid, &status, 0); - assert(WIFEXITED(status)); - return WEXITSTATUS(status); - } else { - // Spawn a thread and call exit() from there, to check that we track main - // thread's pid correctly even if leak checking is initiated from another - // thread. - ExitFromThread(); - } - return 0; -} Index: test/lsan/TestCases/guard-page.c =================================================================== --- /dev/null +++ test/lsan/TestCases/guard-page.c @@ -1,61 +0,0 @@ -// Check that if LSan finds that SP doesn't point into thread stack (e.g. -// if swapcontext is used), LSan will not hit the guard page. -// RUN: %clang_lsan %s -o %t && %run %t -#include -#include -#include -#include -#include -#include - -pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -int ctxfunc_started = 0; - -static void die(const char* msg, int err) { - if (err == 0) - err = errno; - fprintf(stderr, "%s: %s\n", msg, strerror(err)); - exit(EXIT_FAILURE); -} - -static void ctxfunc() { - pthread_mutex_lock(&mutex); - ctxfunc_started = 1; - // printf("ctxfunc\n"); - pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - // Leave this context alive when the program exits. - for (;;); -} - -static void* thread(void* arg) { - (void)arg; - ucontext_t ctx; - void* stack; - - if (getcontext(&ctx) < 0) - die("getcontext", 0); - stack = malloc(1 << 11); - if (stack == NULL) - die("malloc", 0); - ctx.uc_stack.ss_sp = stack; - ctx.uc_stack.ss_size = 1 << 11; - makecontext(&ctx, ctxfunc, 0); - setcontext(&ctx); - die("setcontext", 0); - return NULL; -} - -int main() { - pthread_t tid; - int i; - - pthread_mutex_lock(&mutex); - i = pthread_create(&tid, NULL, thread, NULL); - if (i != 0) - die("pthread_create", i); - while (!ctxfunc_started) pthread_cond_wait(&cond, &mutex); - pthread_mutex_unlock(&mutex); - return 0; -} Index: test/lsan/TestCases/use_tls_dynamic.cc =================================================================== --- /dev/null +++ test/lsan/TestCases/use_tls_dynamic.cc @@ -1,52 +0,0 @@ -// Test that dynamically allocated TLS space is included in the root set. -// 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 -// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=1" %run %t 2>&1 -// RUN: LSAN_OPTIONS="" %run %t 2>&1 -// UNSUPPORTED: i386-linux,i686-linux,arm - -#ifndef BUILD_DSO -#include -#include -#include -#include -#include -#include "sanitizer_common/print_address.h" - -int main(int argc, char *argv[]) { - std::string path = std::string(argv[0]) + "-so.so"; - - void *handle = dlopen(path.c_str(), RTLD_LAZY); - assert(handle != 0); - typedef void **(* store_t)(void *p); - store_t StoreToTLS = (store_t)dlsym(handle, "StoreToTLS"); - assert(dlerror() == 0); - - void *p = malloc(1337); - // If we don't know about dynamic TLS, we will return a false leak above. - void **p_in_tls = StoreToTLS(p); - assert(*p_in_tls == p); - print_address("Test alloc: ", 1, p); - return 0; -} -// CHECK: Test alloc: [[ADDR:0x[0-9,a-f]+]] -// CHECK: LeakSanitizer: detected memory leaks -// CHECK: [[ADDR]] (1337 bytes) -// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: - -#else // BUILD_DSO -// A loadable module with a large thread local section, which would require -// allocation of a new TLS storage chunk when loaded with dlopen(). We use it -// to test the reachability of such chunks in LSan tests. - -// This must be large enough that it doesn't fit into preallocated static TLS -// space (see STATIC_TLS_SURPLUS in glibc). -__thread void *huge_thread_local_array[(1 << 20) / sizeof(void *)]; // NOLINT - -extern "C" void **StoreToTLS(void *p) { - huge_thread_local_array[0] = p; - return &huge_thread_local_array[0]; -} -#endif // BUILD_DSO Index: test/lsan/TestCases/use_tls_pthread_specific_dynamic.cc =================================================================== --- /dev/null +++ test/lsan/TestCases/use_tls_pthread_specific_dynamic.cc @@ -1,38 +0,0 @@ -// Test that dynamically allocated thread-specific storage is included in the root set. -// 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 -// RUN: LSAN_OPTIONS="" %run %t 2>&1 - -#include -#include -#include -#include -#include "sanitizer_common/print_address.h" - -// From glibc: this many keys are stored in the thread descriptor directly. -const unsigned PTHREAD_KEY_2NDLEVEL_SIZE = 32; - -int main() { - static const unsigned kDummyKeysCount = PTHREAD_KEY_2NDLEVEL_SIZE; - int res; - pthread_key_t dummy_keys[kDummyKeysCount]; - for (unsigned i = 0; i < kDummyKeysCount; i++) { - res = pthread_key_create(&dummy_keys[i], NULL); - assert(res == 0); - } - pthread_key_t key; - res = pthread_key_create(&key, NULL); - assert(key >= PTHREAD_KEY_2NDLEVEL_SIZE); - assert(res == 0); - void *p = malloc(1337); - res = pthread_setspecific(key, p); - assert(res == 0); - print_address("Test alloc: ", 1, p); - return 0; -} -// CHECK: Test alloc: [[ADDR:0x[0-9,a-f]+]] -// CHECK: LeakSanitizer: detected memory leaks -// CHECK: [[ADDR]] (1337 bytes) -// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: Index: test/lsan/TestCases/use_tls_pthread_specific_static.cc =================================================================== --- /dev/null +++ test/lsan/TestCases/use_tls_pthread_specific_static.cc @@ -1,32 +0,0 @@ -// Test that statically allocated thread-specific storage is included in the root set. -// 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 -// RUN: LSAN_OPTIONS="" %run %t 2>&1 - -#include -#include -#include -#include -#include "sanitizer_common/print_address.h" - -// From glibc: this many keys are stored in the thread descriptor directly. -const unsigned PTHREAD_KEY_2NDLEVEL_SIZE = 32; - -int main() { - pthread_key_t key; - int res; - res = pthread_key_create(&key, NULL); - assert(res == 0); - assert(key < PTHREAD_KEY_2NDLEVEL_SIZE); - void *p = malloc(1337); - res = pthread_setspecific(key, p); - assert(res == 0); - print_address("Test alloc: ", 1, p); - return 0; -} -// CHECK: Test alloc: [[ADDR:0x[0-9,a-f]+]] -// CHECK: LeakSanitizer: detected memory leaks -// CHECK: [[ADDR]] (1337 bytes) -// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: Index: test/lsan/TestCases/use_tls_static.cc =================================================================== --- /dev/null +++ test/lsan/TestCases/use_tls_static.cc @@ -1,22 +0,0 @@ -// Test that statically allocated TLS space is included in the root set. -// 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 -// RUN: LSAN_OPTIONS="" %run %t 2>&1 - -#include -#include -#include "sanitizer_common/print_address.h" - -__thread void *tls_var; - -int main() { - tls_var = malloc(1337); - print_address("Test alloc: ", 1, tls_var); - return 0; -} -// CHECK: Test alloc: [[ADDR:0x[0-9,a-f]+]] -// CHECK: LeakSanitizer: detected memory leaks -// CHECK: [[ADDR]] (1337 bytes) -// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: