1 // Test that lsan handles tls correctly for many threads
2 // RUN: %clangxx_lsan %s -o %t
3 // RUN: %env_lsan_opts="report_objects=1:use_stacks=0:use_registers=0:use_tls=0" not %run %t 2>&1 | FileCheck %s
4 // RUN: %env_lsan_opts="report_objects=1:use_stacks=0:use_registers=0:use_tls=1" %run %t 2>&1
5 // RUN: %env_lsan_opts="" %run %t 2>&1
7 // On glibc, this requires the range returned by GetTLS to include
8 // specific_1stblock and specific in `struct pthread`.
9 // UNSUPPORTED: arm-linux, armhf-linux
11 // TSD on NetBSD does not use TLS
12 // UNSUPPORTED: netbsd
20 static const int NUM_THREADS
= 10;
22 pthread_cond_t cond
= PTHREAD_COND_INITIALIZER
;
23 pthread_mutex_t mutex
= PTHREAD_MUTEX_INITIALIZER
;
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
29 pthread_key_t keys
[PTHREAD_KEYS_MAX
];
30 static const int PTHREAD_KEY_INVALID
= 0xffffffff;
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
)) {
42 void pthread_destructor(void *arg
) {
43 assert(0 && "pthread destructors shouldn't be called");
46 void *thread_start(void *arg
) {
49 pthread_mutex_lock(&mutex
);
51 pthread_mutex_unlock(&mutex
);
53 // don't exit, to intentionally leak tls data
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
;
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));
70 // spin until all threads have finished
71 while (finished
< NUM_THREADS
)
76 // CHECK: LeakSanitizer: detected memory leaks
77 // CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: