diff options
-rw-r--r-- | compiler-rt/lib/lsan/lsan_common.cc | 1 | ||||
-rw-r--r-- | compiler-rt/test/asan/TestCases/Linux/pthread_create_from_constructor.cc | 48 |
2 files changed, 49 insertions, 0 deletions
diff --git a/compiler-rt/lib/lsan/lsan_common.cc b/compiler-rt/lib/lsan/lsan_common.cc index f1ab2e6296a..b20941ef23f 100644 --- a/compiler-rt/lib/lsan/lsan_common.cc +++ b/compiler-rt/lib/lsan/lsan_common.cc @@ -32,6 +32,7 @@ namespace __lsan { // also to protect the global list of root regions. BlockingMutex global_mutex(LINKER_INITIALIZED); +__attribute__((tls_model("initial-exec"))) THREADLOCAL int disable_counter; bool DisabledInThisThread() { return disable_counter > 0; } void DisableInThisThread() { disable_counter++; } diff --git a/compiler-rt/test/asan/TestCases/Linux/pthread_create_from_constructor.cc b/compiler-rt/test/asan/TestCases/Linux/pthread_create_from_constructor.cc new file mode 100644 index 00000000000..ddd07a718d1 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Linux/pthread_create_from_constructor.cc @@ -0,0 +1,48 @@ +// Test that ASan doesn't deadlock in __interceptor_pthread_create called +// from dlopened shared library constructor. The deadlock happens only in shared +// ASan runtime with recent Glibc (2.23 fits) when __interceptor_pthread_create +// grabs global Glibc's GL(dl_load_lock) and waits for tls_get_addr_tail that +// also tries to acquire it. +// +// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t-so.so +// RUN: %clangxx_asan %s -o %t +// RUN: %run %t 2>&1 + +// dlopen() can not be intercepted on Android +// UNSUPPORTED: android + +#ifdef BUILD_SO + +#include <stdio.h> +#include <pthread.h> +#include <unistd.h> + +void *threadFn(void *) { + fprintf(stderr, "thread started\n"); + while (true) { + usleep(100000); + } + return 0; +} + +void __attribute__((constructor)) startPolling() { + fprintf(stderr, "initializing library\n"); + pthread_t t; + pthread_create(&t, 0, &threadFn, 0); + fprintf(stderr, "done\n"); +} + +#else + +#include <dlfcn.h> +#include <stdlib.h> +#include <string> + +int main(int argc, char **argv) { + std::string path = std::string(argv[0]) + "-so.so"; + void *handle = dlopen(path.c_str(), RTLD_LAZY); + if (!handle) + abort(); + return 0; +} +#endif |