1 // RUN: rm -rf %t-dir 2 // RUN: mkdir %t-dir 3 // RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %t-dir/libignore_lib.so 4 // RUN: %clangxx_tsan -O1 %s %link_libcxx_tsan -o %t-dir/executable 5 // RUN: %env_tsan_opts=suppressions='%s.supp' %run %t-dir/executable 2>&1 | FileCheck %s 6 7 // Copied from ignore_lib5.cpp: 8 // REQUIRES: stable-runtime 9 // UNSUPPORTED: powerpc64le 10 // UNSUPPORTED: netbsd 11 12 // Test that pthread_detach works in libraries ignored by called_from_lib. 13 // For more context see: 14 // https://groups.google.com/forum/#!topic/thread-sanitizer/ecH2P0QUqPs 15 16 #include "test.h" 17 #include <dlfcn.h> 18 #include <errno.h> 19 #include <libgen.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string> 23 #include <sys/mman.h> 24 25 #ifndef LIB 26 27 void *thr(void *arg) { 28 *(volatile long long *)arg = 1; 29 return 0; 30 } 31 32 int main(int argc, char **argv) { 33 std::string lib = std::string(dirname(argv[0])) + "/libignore_lib.so"; 34 void *h = dlopen(lib.c_str(), RTLD_GLOBAL | RTLD_NOW); 35 if (h == 0) 36 exit(printf("failed to load the library (%d)\n", errno)); 37 void (*libfunc)() = (void (*)())dlsym(h, "libfunc"); 38 if (libfunc == 0) 39 exit(printf("failed to find the func (%d)\n", errno)); 40 libfunc(); 41 42 const int kThreads = 10; 43 pthread_t t[kThreads]; 44 volatile long long data[kThreads]; 45 for (int i = 0; i < kThreads; i++) 46 pthread_create(&t[i], 0, thr, (void *)&data[i]); 47 for (int i = 0; i < kThreads; i++) { 48 pthread_join(t[i], 0); 49 data[i] = 2; 50 } 51 fprintf(stderr, "DONE\n"); 52 } 53 54 // CHECK-NOT: WARNING: ThreadSanitizer: 55 // CHECK: DONE 56 // CHECK-NOT: WARNING: ThreadSanitizer: 57 58 #else // #ifdef LIB 59 60 void *thr(void *p) { 61 sleep(1); 62 pthread_detach(pthread_self()); 63 return 0; 64 } 65 66 extern "C" void libfunc() { 67 const int kThreads = 10; 68 pthread_t t[kThreads]; 69 for (int i = 0; i < kThreads; i++) 70 pthread_create(&t[i], 0, thr, 0); 71 sleep(2); 72 } 73 74 #endif // #ifdef LIB 75