xref: /llvm-project/compiler-rt/test/tsan/dl_iterate_phdr.cpp (revision bcaeed49cb063de9fe504aa29e1cadff8a7be710)
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