1*bcaeed49SFangrui Song // RUN: %clangxx_tsan -O1 %s -DBUILD_SO -fPIC -shared -o %t-so.so
2*bcaeed49SFangrui Song // RUN: %clangxx_tsan -O1 %s %link_libcxx_tsan -o %t && %run %t 2>&1 | FileCheck %s
3*bcaeed49SFangrui Song
4*bcaeed49SFangrui Song // dl_iterate_phdr doesn't exist on OS X.
5*bcaeed49SFangrui Song // UNSUPPORTED: darwin
6*bcaeed49SFangrui Song
7*bcaeed49SFangrui Song #ifdef BUILD_SO
8*bcaeed49SFangrui Song
9*bcaeed49SFangrui Song #include "test.h"
10*bcaeed49SFangrui Song
11*bcaeed49SFangrui Song int exported_var = 0;
12*bcaeed49SFangrui Song
13*bcaeed49SFangrui Song #else // BUILD_SO
14*bcaeed49SFangrui Song
15*bcaeed49SFangrui Song #include "test.h"
16*bcaeed49SFangrui Song #include <dlfcn.h>
17*bcaeed49SFangrui Song #include <link.h>
18*bcaeed49SFangrui Song #include <string.h>
19*bcaeed49SFangrui Song #include <string>
20*bcaeed49SFangrui Song
callback(struct dl_phdr_info * info,size_t size,void * data)21*bcaeed49SFangrui Song static int callback(struct dl_phdr_info *info, size_t size, void *data) {
22*bcaeed49SFangrui Song if (info->dlpi_name[0] == '\0')
23*bcaeed49SFangrui Song info->dlpi_name = "/proc/self/exe";
24*bcaeed49SFangrui Song return !strcmp(info->dlpi_name, "non existent module");
25*bcaeed49SFangrui Song }
26*bcaeed49SFangrui Song
thread(void * unused)27*bcaeed49SFangrui Song void *thread(void *unused) {
28*bcaeed49SFangrui Song for (int i = 0; i < 1000; i++) {
29*bcaeed49SFangrui Song barrier_wait(&barrier);
30*bcaeed49SFangrui Song dl_iterate_phdr(callback, 0);
31*bcaeed49SFangrui Song }
32*bcaeed49SFangrui Song return 0;
33*bcaeed49SFangrui Song }
34*bcaeed49SFangrui Song
main(int argc,char * argv[])35*bcaeed49SFangrui Song int main(int argc, char *argv[]) {
36*bcaeed49SFangrui Song barrier_init(&barrier, 2);
37*bcaeed49SFangrui Song std::string path = std::string(argv[0]) + std::string("-so.so");
38*bcaeed49SFangrui Song pthread_t th;
39*bcaeed49SFangrui Song pthread_create(&th, 0, thread, 0);
40*bcaeed49SFangrui Song for (int i = 0; i < 1000; i++) {
41*bcaeed49SFangrui Song barrier_wait(&barrier);
42*bcaeed49SFangrui Song void *lib = dlopen(path.c_str(), RTLD_NOW);
43*bcaeed49SFangrui Song if (!lib) {
44*bcaeed49SFangrui Song printf("error in dlopen: %s\n", dlerror());
45*bcaeed49SFangrui Song return 1;
46*bcaeed49SFangrui Song }
47*bcaeed49SFangrui Song dlclose(lib);
48*bcaeed49SFangrui Song }
49*bcaeed49SFangrui Song pthread_join(th, 0);
50*bcaeed49SFangrui Song fprintf(stderr, "DONE\n");
51*bcaeed49SFangrui Song return 0;
52*bcaeed49SFangrui Song }
53*bcaeed49SFangrui Song
54*bcaeed49SFangrui Song #endif // BUILD_SO
55*bcaeed49SFangrui Song
56*bcaeed49SFangrui Song // CHECK-NOT: WARNING: ThreadSanitizer: data race
57*bcaeed49SFangrui Song // CHECK: DONE
58