78 lines · cpp
1// Test that lsan handles tls correctly for many threads2// RUN: %clangxx_lsan %s -o %t3// RUN: %env_lsan_opts="report_objects=1:use_stacks=0:use_registers=0:use_tls=0" not %run %t 2>&1 | FileCheck %s4// RUN: %env_lsan_opts="report_objects=1:use_stacks=0:use_registers=0:use_tls=1" %run %t 2>&15// RUN: %env_lsan_opts="" %run %t 2>&16 7// On glibc, this requires the range returned by GetTLS to include8// specific_1stblock and specific in `struct pthread`.9// UNSUPPORTED: arm-linux, armhf-linux10 11// TSD on NetBSD does not use TLS12// UNSUPPORTED: target={{.*netbsd.*}}13 14#include <assert.h>15#include <limits.h>16#include <pthread.h>17#include <stdlib.h>18#include <unistd.h>19 20static const int NUM_THREADS = 10;21 22pthread_cond_t cond = PTHREAD_COND_INITIALIZER;23pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;24int finished = 0;25 26// We won't be able to create the maximum number of keys, due to other users27// of the tls, but we'll use as many keys as we can before failing to create28// a new key.29pthread_key_t keys[PTHREAD_KEYS_MAX];30static const int PTHREAD_KEY_INVALID = 0xffffffff;31 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 42void pthread_destructor(void *arg) {43 assert(0 && "pthread destructors shouldn't be called");44}45 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 data54 while (1)55 sleep(100);56}57 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 finished71 while (finished < NUM_THREADS)72 sleep(1);73 exit(0);74}75 76// CHECK: LeakSanitizer: detected memory leaks77// CHECK: SUMMARY: {{.*}}Sanitizer:78