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  | 

