aboutsummaryrefslogtreecommitdiff
path: root/test/tsan/dlclose.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/tsan/dlclose.cc')
-rw-r--r--test/tsan/dlclose.cc58
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
+