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 // Test case for
5*bcaeed49SFangrui Song // https://github.com/google/sanitizers/issues/487
6*bcaeed49SFangrui Song 
7*bcaeed49SFangrui Song #ifdef BUILD_SO
8*bcaeed49SFangrui Song 
9*bcaeed49SFangrui Song #include <stdio.h>
10*bcaeed49SFangrui Song 
11*bcaeed49SFangrui Song extern "C"
sofunc()12*bcaeed49SFangrui Song void sofunc() {
13*bcaeed49SFangrui Song   fprintf(stderr, "HELLO FROM SO\n");
14*bcaeed49SFangrui Song }
15*bcaeed49SFangrui Song 
16*bcaeed49SFangrui Song #else  // BUILD_SO
17*bcaeed49SFangrui Song 
18*bcaeed49SFangrui Song #include <dlfcn.h>
19*bcaeed49SFangrui Song #include <stdio.h>
20*bcaeed49SFangrui Song #include <stddef.h>
21*bcaeed49SFangrui Song #include <unistd.h>
22*bcaeed49SFangrui Song #include <string>
23*bcaeed49SFangrui Song 
24*bcaeed49SFangrui Song void *lib;
25*bcaeed49SFangrui Song void *lib2;
26*bcaeed49SFangrui Song 
27*bcaeed49SFangrui Song struct Closer {
~CloserCloser28*bcaeed49SFangrui Song   ~Closer() {
29*bcaeed49SFangrui Song     dlclose(lib);
30*bcaeed49SFangrui Song     fprintf(stderr, "CLOSED SO\n");
31*bcaeed49SFangrui Song   }
32*bcaeed49SFangrui Song };
33*bcaeed49SFangrui Song static Closer c;
34*bcaeed49SFangrui Song 
main(int argc,char * argv[])35*bcaeed49SFangrui Song int main(int argc, char *argv[]) {
36*bcaeed49SFangrui Song   lib = dlopen((std::string(argv[0]) + std::string("-so.so")).c_str(),
37*bcaeed49SFangrui Song       RTLD_NOW|RTLD_NODELETE);
38*bcaeed49SFangrui Song   if (lib == 0) {
39*bcaeed49SFangrui Song     printf("error in dlopen: %s\n", dlerror());
40*bcaeed49SFangrui Song     return 1;
41*bcaeed49SFangrui Song   }
42*bcaeed49SFangrui Song   void *f = dlsym(lib, "sofunc");
43*bcaeed49SFangrui Song   if (f == 0) {
44*bcaeed49SFangrui Song     printf("error in dlsym: %s\n", dlerror());
45*bcaeed49SFangrui Song     return 1;
46*bcaeed49SFangrui Song   }
47*bcaeed49SFangrui Song   ((void(*)())f)();
48*bcaeed49SFangrui Song   return 0;
49*bcaeed49SFangrui Song }
50*bcaeed49SFangrui Song 
51*bcaeed49SFangrui Song #endif  // BUILD_SO
52*bcaeed49SFangrui Song 
53*bcaeed49SFangrui Song // CHECK: HELLO FROM SO
54*bcaeed49SFangrui Song // CHECK-NOT: Inconsistency detected by ld.so
55*bcaeed49SFangrui Song // CHECK: CLOSED SO
56*bcaeed49SFangrui Song 
57