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