--- /dev/null
+// 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 <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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)
--- /dev/null
+// 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 <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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;
+}
--- /dev/null
+// Test that thread local data is handled correctly after forking without exec().
+// RUN: %clangxx_lsan %s -o %t
+// RUN: %run %t 2>&1
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+__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;
+}
--- /dev/null
+// 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 <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+__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;
+}
--- /dev/null
+// 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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <ucontext.h>
+
+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;
+}
--- /dev/null
+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
--- /dev/null
+// 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 <assert.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+#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
--- /dev/null
+// 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 <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#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:
--- /dev/null
+// 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 <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#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:
--- /dev/null
+// 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 <stdio.h>
+#include <stdlib.h>
+#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:
+++ /dev/null
-// 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 <assert.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#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)
+++ /dev/null
-// 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 <assert.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#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;
-}
+++ /dev/null
-// Test that thread local data is handled correctly after forking without exec().
-// RUN: %clangxx_lsan %s -o %t
-// RUN: %run %t 2>&1
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-__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;
-}
+++ /dev/null
-// 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 <assert.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-__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;
-}
+++ /dev/null
-// 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 <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <ucontext.h>
-
-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;
-}
+++ /dev/null
-// 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 <assert.h>
-#include <dlfcn.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string>
-#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
+++ /dev/null
-// 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 <assert.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#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:
+++ /dev/null
-// 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 <assert.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#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:
+++ /dev/null
-// 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 <stdio.h>
-#include <stdlib.h>
-#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: