Index: compiler-rt/trunk/test/lsan/TestCases/Linux/cleanup_in_tsd_destructor.c =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/Linux/cleanup_in_tsd_destructor.c +++ compiler-rt/trunk/test/lsan/TestCases/Linux/cleanup_in_tsd_destructor.c @@ -0,0 +1,46 @@ +// 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: compiler-rt/trunk/test/lsan/TestCases/Linux/disabler_in_tsd_destructor.c =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/Linux/disabler_in_tsd_destructor.c +++ compiler-rt/trunk/test/lsan/TestCases/Linux/disabler_in_tsd_destructor.c @@ -0,0 +1,39 @@ +// 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: compiler-rt/trunk/test/lsan/TestCases/Linux/fork.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/Linux/fork.cc +++ compiler-rt/trunk/test/lsan/TestCases/Linux/fork.cc @@ -0,0 +1,24 @@ +// 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: compiler-rt/trunk/test/lsan/TestCases/Linux/fork_threaded.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/Linux/fork_threaded.cc +++ compiler-rt/trunk/test/lsan/TestCases/Linux/fork_threaded.cc @@ -0,0 +1,43 @@ +// 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: compiler-rt/trunk/test/lsan/TestCases/Linux/guard-page.c =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/Linux/guard-page.c +++ compiler-rt/trunk/test/lsan/TestCases/Linux/guard-page.c @@ -0,0 +1,61 @@ +// 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: compiler-rt/trunk/test/lsan/TestCases/Linux/lit.local.cfg =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/Linux/lit.local.cfg +++ compiler-rt/trunk/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: compiler-rt/trunk/test/lsan/TestCases/Linux/use_tls_dynamic.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/Linux/use_tls_dynamic.cc +++ compiler-rt/trunk/test/lsan/TestCases/Linux/use_tls_dynamic.cc @@ -0,0 +1,52 @@ +// 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: compiler-rt/trunk/test/lsan/TestCases/Linux/use_tls_pthread_specific_dynamic.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/Linux/use_tls_pthread_specific_dynamic.cc +++ compiler-rt/trunk/test/lsan/TestCases/Linux/use_tls_pthread_specific_dynamic.cc @@ -0,0 +1,38 @@ +// 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: compiler-rt/trunk/test/lsan/TestCases/Linux/use_tls_pthread_specific_static.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/Linux/use_tls_pthread_specific_static.cc +++ compiler-rt/trunk/test/lsan/TestCases/Linux/use_tls_pthread_specific_static.cc @@ -0,0 +1,32 @@ +// 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: compiler-rt/trunk/test/lsan/TestCases/Linux/use_tls_static.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/Linux/use_tls_static.cc +++ compiler-rt/trunk/test/lsan/TestCases/Linux/use_tls_static.cc @@ -0,0 +1,22 @@ +// 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: Index: compiler-rt/trunk/test/lsan/TestCases/cleanup_in_tsd_destructor.c =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/cleanup_in_tsd_destructor.c +++ compiler-rt/trunk/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: compiler-rt/trunk/test/lsan/TestCases/disabler_in_tsd_destructor.c =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/disabler_in_tsd_destructor.c +++ compiler-rt/trunk/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: compiler-rt/trunk/test/lsan/TestCases/fork.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/fork.cc +++ compiler-rt/trunk/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: compiler-rt/trunk/test/lsan/TestCases/fork_threaded.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/fork_threaded.cc +++ compiler-rt/trunk/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: compiler-rt/trunk/test/lsan/TestCases/guard-page.c =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/guard-page.c +++ compiler-rt/trunk/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: compiler-rt/trunk/test/lsan/TestCases/use_tls_dynamic.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/use_tls_dynamic.cc +++ compiler-rt/trunk/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: compiler-rt/trunk/test/lsan/TestCases/use_tls_pthread_specific_dynamic.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/use_tls_pthread_specific_dynamic.cc +++ compiler-rt/trunk/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: compiler-rt/trunk/test/lsan/TestCases/use_tls_pthread_specific_static.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/use_tls_pthread_specific_static.cc +++ compiler-rt/trunk/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: compiler-rt/trunk/test/lsan/TestCases/use_tls_static.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/use_tls_static.cc +++ compiler-rt/trunk/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: