Home | History | Annotate | Download | only in tsan
      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 -rdynamic && %deflake %run %t | FileCheck %s
      7 
      8 #ifdef BUILD_SO
      9 
     10 #include "test.h"
     11 
     12 int GLOB_SHARED = 0;
     13 
     14 extern "C"
     15 void init_so() {
     16   barrier_init(&barrier, 2);
     17 }
     18 
     19 extern "C"
     20 void *write_from_so(void *unused) {
     21   if (unused == 0)
     22     barrier_wait(&barrier);
     23   GLOB_SHARED++;
     24   if (unused != 0)
     25     barrier_wait(&barrier);
     26   return NULL;
     27 }
     28 
     29 #else  // BUILD_SO
     30 
     31 #include "test.h"
     32 #include <dlfcn.h>
     33 #include <string>
     34 
     35 int GLOB = 0;
     36 
     37 void *write_glob(void *unused) {
     38   if (unused == 0)
     39     barrier_wait(&barrier);
     40   GLOB++;
     41   if (unused != 0)
     42     barrier_wait(&barrier);
     43   return NULL;
     44 }
     45 
     46 void race_two_threads(void *(*access_callback)(void *unused)) {
     47   pthread_t t1, t2;
     48   pthread_create(&t1, NULL, access_callback, (void*)1);
     49   pthread_create(&t2, NULL, access_callback, NULL);
     50   pthread_join(t1, NULL);
     51   pthread_join(t2, NULL);
     52 }
     53 
     54 int main(int argc, char *argv[]) {
     55   barrier_init(&barrier, 2);
     56   std::string path = std::string(argv[0]) + std::string("-so.so");
     57   race_two_threads(write_glob);
     58   // CHECK: write_glob
     59   void *lib = dlopen(path.c_str(), RTLD_NOW);
     60     if (!lib) {
     61     printf("error in dlopen(): %s\n", dlerror());
     62     return 1;
     63   }
     64   void (*init_so)();
     65   *(void **)&init_so = dlsym(lib, "init_so");
     66   init_so();
     67   void *(*write_from_so)(void *unused);
     68   *(void **)&write_from_so = dlsym(lib, "write_from_so");
     69   race_two_threads(write_from_so);
     70   // CHECK: write_from_so
     71   return 0;
     72 }
     73 
     74 #endif  // BUILD_SO
     75