1 | // Test that ASan doesn't deadlock in __interceptor_pthread_create called |
2 | // from dlopened shared library constructor. The deadlock happens only in shared |
3 | // ASan runtime with recent Glibc (2.23 fits) when __interceptor_pthread_create |
4 | // grabs global Glibc's GL(dl_load_lock) and waits for tls_get_addr_tail that |
5 | // also tries to acquire it. |
6 | // |
7 | // RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t-so.so |
8 | // RUN: %clangxx_asan %s -o %t |
9 | // RUN: %run %t 2>&1 |
10 | |
11 | // dlopen() can not be intercepted on Android |
12 | // UNSUPPORTED: android |
13 | // REQUIRES: x86-target-arch |
14 | |
15 | #ifdef BUILD_SO |
16 | |
17 | #include <stdio.h> |
18 | #include <pthread.h> |
19 | #include <unistd.h> |
20 | |
21 | void *threadFn(void *) { |
22 | fprintf(stderr, "thread started\n" ); |
23 | while (true) { |
24 | usleep(100000); |
25 | } |
26 | return 0; |
27 | } |
28 | |
29 | void __attribute__((constructor)) startPolling() { |
30 | fprintf(stderr, "initializing library\n" ); |
31 | pthread_t t; |
32 | pthread_create(&t, 0, &threadFn, 0); |
33 | fprintf(stderr, "done\n" ); |
34 | } |
35 | |
36 | #else |
37 | |
38 | #include <dlfcn.h> |
39 | #include <stdlib.h> |
40 | #include <string> |
41 | |
42 | int main(int argc, char **argv) { |
43 | std::string path = std::string(argv[0]) + "-so.so" ; |
44 | void *handle = dlopen(file: path.c_str(), RTLD_LAZY); |
45 | if (!handle) |
46 | abort(); |
47 | return 0; |
48 | } |
49 | #endif |
50 | |