aboutsummaryrefslogtreecommitdiff
path: root/test/asan/TestCases/Linux/pthread_create_from_constructor.cc
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:27 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:27 +0000
commit316d58822dada9440bd06ecfc758dcc2364d617c (patch)
treefe72ec2e6ce9a360dda74d9d57f7acdb0e3c39d6 /test/asan/TestCases/Linux/pthread_create_from_constructor.cc
parent0230fcf22fe7d19f03d981c9c2c59a3db0b72ea5 (diff)
Notes
Diffstat (limited to 'test/asan/TestCases/Linux/pthread_create_from_constructor.cc')
-rw-r--r--test/asan/TestCases/Linux/pthread_create_from_constructor.cc49
1 files changed, 49 insertions, 0 deletions
diff --git a/test/asan/TestCases/Linux/pthread_create_from_constructor.cc b/test/asan/TestCases/Linux/pthread_create_from_constructor.cc
new file mode 100644
index 000000000000..8f9b0b4fed1a
--- /dev/null
+++ b/test/asan/TestCases/Linux/pthread_create_from_constructor.cc
@@ -0,0 +1,49 @@
+// Test that ASan doesn't deadlock in __interceptor_pthread_create called
+// from dlopened shared library constructor. The deadlock happens only in shared
+// ASan runtime with recent Glibc (2.23 fits) when __interceptor_pthread_create
+// grabs global Glibc's GL(dl_load_lock) and waits for tls_get_addr_tail that
+// also tries to acquire it.
+//
+// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t-so.so
+// RUN: %clangxx_asan %s -o %t
+// RUN: %run %t 2>&1
+
+// dlopen() can not be intercepted on Android
+// UNSUPPORTED: android
+// REQUIRES: x86-target-arch
+
+#ifdef BUILD_SO
+
+#include <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+
+void *threadFn(void *) {
+ fprintf(stderr, "thread started\n");
+ while (true) {
+ usleep(100000);
+ }
+ return 0;
+}
+
+void __attribute__((constructor)) startPolling() {
+ fprintf(stderr, "initializing library\n");
+ pthread_t t;
+ pthread_create(&t, 0, &threadFn, 0);
+ fprintf(stderr, "done\n");
+}
+
+#else
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <string>
+
+int main(int argc, char **argv) {
+ std::string path = std::string(argv[0]) + "-so.so";
+ void *handle = dlopen(path.c_str(), RTLD_LAZY);
+ if (!handle)
+ abort();
+ return 0;
+}
+#endif