diff options
Diffstat (limited to 'test/tsan/dlclose.cc')
-rw-r--r-- | test/tsan/dlclose.cc | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/test/tsan/dlclose.cc b/test/tsan/dlclose.cc new file mode 100644 index 000000000000..1a93fe6617e1 --- /dev/null +++ b/test/tsan/dlclose.cc @@ -0,0 +1,58 @@ +// RUN: %clangxx_tsan -O1 %s -DBUILD_SO -fPIC -shared -o %t-so.so +// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s + +// If we mention TSAN_OPTIONS, the test won't run from test_output.sh script. + +// Test case for +// https://code.google.com/p/thread-sanitizer/issues/detail?id=80 + +#ifdef BUILD_SO + +#include <stdio.h> + +extern "C" +void sofunc() { + fprintf(stderr, "HELLO FROM SO\n"); +} + +#else // BUILD_SO + +#include <dlfcn.h> +#include <stdio.h> +#include <stddef.h> +#include <unistd.h> +#include <string> + +void *lib; +void *lib2; + +struct Closer { + ~Closer() { + dlclose(lib); + fprintf(stderr, "CLOSED SO\n"); + } +}; +static Closer c; + +int main(int argc, char *argv[]) { + lib = dlopen((std::string(argv[0]) + std::string("-so.so")).c_str(), + RTLD_NOW|RTLD_NODELETE); + if (lib == 0) { + printf("error in dlopen: %s\n", dlerror()); + return 1; + } + void *f = dlsym(lib, "sofunc"); + if (f == 0) { + printf("error in dlsym: %s\n", dlerror()); + return 1; + } + ((void(*)())f)(); + return 0; +} + +#endif // BUILD_SO + +// CHECK: HELLO FROM SO +// CHECK-NOT: Inconsistency detected by ld.so +// CHECK: CLOSED SO + |