aboutsummaryrefslogtreecommitdiff
path: root/lib/tsan/lit_tests/load_shared_lib.cc
blob: d60cd5700a8a50cef4d3857847366f68ad7838b2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// Check that if the list of shared libraries changes between the two race
// reports, the second report occurring in a new shared library is still
// symbolized correctly.

// RUN: %clangxx_tsan -O1 %p/SharedLibs/load_shared_lib-so.cc \
// RUN:     -fPIC -shared -o %t-so.so
// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s

#include <dlfcn.h>
#include <pthread.h>
#include <stdio.h>

#include <string>

int GLOB = 0;

void *write_glob(void *unused) {
  GLOB++;
  return NULL;
}

void race_two_threads(void *(*access_callback)(void *unused)) {
  pthread_t t1, t2;
  pthread_create(&t1, NULL, access_callback, NULL);
  pthread_create(&t2, NULL, access_callback, NULL);
  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
}

int main(int argc, char *argv[]) {
  std::string path = std::string(argv[0]) + std::string("-so.so");
  race_two_threads(write_glob);
  // CHECK: write_glob
  void *lib = dlopen(path.c_str(), RTLD_NOW);
    if (!lib) {
    printf("error in dlopen(): %s\n", dlerror());
    return 1;
  }
  void *(*write_from_so)(void *unused);
  *(void **)&write_from_so = dlsym(lib, "write_from_so");
  race_two_threads(write_from_so);
  // CHECK: write_from_so
  return 0;
}