75 lines · cpp
1// Check that if the list of shared libraries changes between the two race2// reports, the second report occurring in a new shared library is still3// symbolized correctly.4 5// RUN: %clangxx_tsan -O1 %s -DBUILD_SO -fPIC -shared -o %t-so.so6// RUN: %clangxx_tsan -O1 %s %link_libcxx_tsan -o %t -rdynamic && %deflake %run %t | FileCheck %s7 8#ifdef BUILD_SO9 10#include "test.h"11 12int GLOB_SHARED = 0;13 14extern "C"15void init_so() {16 barrier_init(&barrier, 2);17}18 19extern "C"20void *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_SO30 31#include "test.h"32#include <dlfcn.h>33#include <string>34 35int GLOB = 0;36 37void *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 46void 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 54int 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_glob59 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_so71 return 0;72}73 74#endif // BUILD_SO75