1 // Check that if the list of shared libraries changes between the two race 2 // reports, the second report occurring in a new shared library is still 3 // symbolized correctly. 4 5 // RUN: %clangxx_tsan -O1 %s -DBUILD_SO -fPIC -shared -o %t-so.so 6 // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s 7 8 #ifdef BUILD_SO 9 10 #include <stddef.h> 11 #include <unistd.h> 12 13 int GLOB_SHARED = 0; 14 15 extern "C" 16 void *write_from_so(void *unused) { 17 if (unused) 18 sleep(1); 19 GLOB_SHARED++; 20 return NULL; 21 } 22 23 #else // BUILD_SO 24 25 #include <dlfcn.h> 26 #include <pthread.h> 27 #include <stdio.h> 28 #include <stddef.h> 29 #include <unistd.h> 30 31 #include <string> 32 33 int GLOB = 0; 34 35 void *write_glob(void *unused) { 36 if (unused) 37 sleep(1); 38 GLOB++; 39 return NULL; 40 } 41 42 void race_two_threads(void *(*access_callback)(void *unused)) { 43 pthread_t t1, t2; 44 pthread_create(&t1, NULL, access_callback, (void*)1); 45 pthread_create(&t2, NULL, access_callback, NULL); 46 pthread_join(t1, NULL); 47 pthread_join(t2, NULL); 48 } 49 50 int main(int argc, char *argv[]) { 51 std::string path = std::string(argv[0]) + std::string("-so.so"); 52 race_two_threads(write_glob); 53 // CHECK: write_glob 54 void *lib = dlopen(path.c_str(), RTLD_NOW); 55 if (!lib) { 56 printf("error in dlopen(): %s\n", dlerror()); 57 return 1; 58 } 59 void *(*write_from_so)(void *unused); 60 *(void **)&write_from_so = dlsym(lib, "write_from_so"); 61 race_two_threads(write_from_so); 62 // CHECK: write_from_so 63 return 0; 64 } 65 66 #endif // BUILD_SO 67