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.
5 // RUN: %clangxx_tsan -O1 %s -DBUILD_SO -fPIC -shared -o %t-so.so
6 // RUN: %clangxx_tsan -O1 %s %link_libcxx_tsan -o %t -rdynamic && %deflake %run %t | FileCheck %s
16 barrier_init(&barrier
, 2);
20 void *write_from_so(void *unused
) {
22 barrier_wait(&barrier
);
25 barrier_wait(&barrier
);
37 void *write_glob(void *unused
) {
39 barrier_wait(&barrier
);
42 barrier_wait(&barrier
);
46 void race_two_threads(void *(*access_callback
)(void *unused
)) {
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
);
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
);
59 void *lib
= dlopen(path
.c_str(), RTLD_NOW
);
61 printf("error in dlopen(): %s\n", dlerror());
65 *(void **)&init_so
= dlsym(lib
, "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