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