1 // Test that lsan handles tls correctly for many threads 2 // RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0" 3 // RUN: %clangxx_lsan %s -o %t 4 // RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=0" not %run %t 2>&1 | FileCheck %s 5 // RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=1" %run %t 2>&1 6 // RUN: %env_lsan_opts="" %run %t 2>&1 7 8 // Patch r303906 did not fix all the problems. 9 // UNSUPPORTED: arm-linux,armhf-linux 10 11 // TSD on NetBSD does not use TLS 12 // UNSUPPORTED: netbsd 13 14 #include <assert.h> 15 #include <limits.h> 16 #include <pthread.h> 17 #include <stdlib.h> 18 #include <unistd.h> 19 20 static const int NUM_THREADS = 10; 21 22 pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 23 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 24 int finished = 0; 25 26 // We won't be able to create the maximum number of keys, due to other users 27 // of the tls, but we'll use as many keys as we can before failing to create 28 // a new key. 29 pthread_key_t keys[PTHREAD_KEYS_MAX]; 30 static const int PTHREAD_KEY_INVALID = 0xffffffff; 31 alloc()32void alloc() { 33 for (int i = 0; i < PTHREAD_KEYS_MAX; ++i) { 34 void *ptr = malloc(123); 35 if ((keys[i] == PTHREAD_KEY_INVALID) || pthread_setspecific(keys[i], ptr)) { 36 free(ptr); 37 break; 38 } 39 } 40 } 41 pthread_destructor(void * arg)42void pthread_destructor(void *arg) { 43 assert(0 && "pthread destructors shouldn't be called"); 44 } 45 thread_start(void * arg)46void *thread_start(void *arg) { 47 alloc(); 48 49 pthread_mutex_lock(&mutex); 50 finished++; 51 pthread_mutex_unlock(&mutex); 52 53 // don't exit, to intentionally leak tls data 54 while (1) 55 sleep(100); 56 } 57 main()58int main() { 59 for (int i = 0; i < PTHREAD_KEYS_MAX; ++i) { 60 if (pthread_key_create(&keys[i], pthread_destructor)) { 61 keys[i] = PTHREAD_KEY_INVALID; 62 break; 63 } 64 } 65 66 pthread_t thread[NUM_THREADS]; 67 for (int i = 0; i < NUM_THREADS; ++i) { 68 assert(0 == pthread_create(&thread[i], 0, thread_start, 0)); 69 } 70 // spin until all threads have finished 71 while (finished < NUM_THREADS) 72 sleep(1); 73 exit(0); 74 } 75 76 // CHECK: LeakSanitizer: detected memory leaks 77 // CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: 78