summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/asan/asan_interceptors.cc6
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc6
-rw-r--r--compiler-rt/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc4
-rw-r--r--compiler-rt/test/asan/TestCases/Linux/init-order-dlopen.cc43
-rw-r--r--compiler-rt/test/asan/TestCases/Posix/init-order-dlopen.cc72
-rw-r--r--compiler-rt/test/asan/TestCases/init-order-pthread-create.cc37
6 files changed, 81 insertions, 87 deletions
diff --git a/compiler-rt/lib/asan/asan_interceptors.cc b/compiler-rt/lib/asan/asan_interceptors.cc
index 3dc7ec67a3e..df57696921d 100644
--- a/compiler-rt/lib/asan/asan_interceptors.cc
+++ b/compiler-rt/lib/asan/asan_interceptors.cc
@@ -171,6 +171,12 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
do { \
} while (false)
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
+// Strict init-order checking is dlopen-hostile:
+// https://code.google.com/p/address-sanitizer/issues/detail?id=178
+#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \
+ if (flags()->strict_init_order) { \
+ StopInitOrderChecking(); \
+ }
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \
CoverageUpdateMapping()
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 87c33e18632..2f1930af82b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -22,6 +22,7 @@
// COMMON_INTERCEPTOR_FD_RELEASE
// COMMON_INTERCEPTOR_FD_ACCESS
// COMMON_INTERCEPTOR_SET_THREAD_NAME
+// COMMON_INTERCEPTOR_ON_DLOPEN
// COMMON_INTERCEPTOR_ON_EXIT
// COMMON_INTERCEPTOR_MUTEX_LOCK
// COMMON_INTERCEPTOR_MUTEX_UNLOCK
@@ -101,6 +102,10 @@
#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
#endif
+#ifndef COMMON_INTERCEPTOR_ON_DLOPEN
+#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) {}
+#endif
+
struct FileMetadata {
// For open_memstream().
char **addr;
@@ -4688,6 +4693,7 @@ INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
void *ctx;
COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
+ COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag);
void *res = REAL(dlopen)(filename, flag);
COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
return res;
diff --git a/compiler-rt/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc b/compiler-rt/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc
index d4606f0afb5..54f26f16724 100644
--- a/compiler-rt/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc
+++ b/compiler-rt/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc
@@ -1,2 +1,2 @@
-void *bar(void *input);
-void *glob2 = bar((void*)0x2345);
+void *bar(void *input, bool sleep_before_init);
+void *glob2 = bar((void*)0x2345, true);
diff --git a/compiler-rt/test/asan/TestCases/Linux/init-order-dlopen.cc b/compiler-rt/test/asan/TestCases/Linux/init-order-dlopen.cc
new file mode 100644
index 00000000000..17ba9d0996d
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/Linux/init-order-dlopen.cc
@@ -0,0 +1,43 @@
+// Regression test for
+// https://code.google.com/p/address-sanitizer/issues/detail?id=178
+
+// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
+// RUN: %clangxx_asan -O0 %s %libdl -Wl,--export-dynamic -o %t
+// RUN: env ASAN_OPTIONS=strict_init_order=true %run %t 2>&1
+
+#if defined(SHARED_LIB)
+#include <stdio.h>
+
+struct Bar {
+ Bar(int val) : val(val) { printf("Bar::Bar(%d)\n", val); }
+ int val;
+};
+
+int get_foo_val();
+Bar global_bar(get_foo_val());
+#else // SHARED LIB
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string>
+struct Foo {
+ Foo() : val(42) { printf("Foo::Foo()\n"); }
+ int val;
+};
+
+Foo global_foo;
+
+int get_foo_val() {
+ return global_foo.val;
+}
+
+int main(int argc, char *argv[]) {
+ std::string path = std::string(argv[0]) + "-so.so";
+ void *handle = dlopen(path.c_str(), RTLD_NOW);
+ if (!handle) {
+ printf("error in dlopen(): %s\n", dlerror());
+ return 1;
+ }
+ printf("%d\n", get_foo_val());
+ return 0;
+}
+#endif // SHARED_LIB
diff --git a/compiler-rt/test/asan/TestCases/Posix/init-order-dlopen.cc b/compiler-rt/test/asan/TestCases/Posix/init-order-dlopen.cc
deleted file mode 100644
index 3c6f093b03d..00000000000
--- a/compiler-rt/test/asan/TestCases/Posix/init-order-dlopen.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Regression test for
-// https://code.google.com/p/address-sanitizer/issues/detail?id=178
-
-// Assume we're on Darwin and try to pass -U to the linker. If this flag is
-// unsupported, don't use it.
-// RUN: %clangxx_asan -O0 -DSHARED_LIB %s \
-// RUN: -fPIC -shared -o %t-so.so -Wl,-U,_inc_global || \
-// RUN: %clangxx_asan -O0 -DSHARED_LIB %s \
-// RUN: -fPIC -shared -o %t-so.so
-// If the linker doesn't support --export-dynamic (which is ELF-specific),
-// try to link without that option.
-// FIXME: find a better solution.
-// RUN: %clangxx_asan -O0 %s -pthread %libdl -o %t -Wl,--export-dynamic || \
-// RUN: %clangxx_asan -O0 %s -pthread %libdl -o %t
-// RUN: ASAN_OPTIONS=strict_init_order=true %run %t 2>&1 | FileCheck %s
-#if !defined(SHARED_LIB)
-#include <dlfcn.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <string>
-
-using std::string;
-
-int foo() {
- return 42;
-}
-int global = foo();
-
-__attribute__((visibility("default")))
-extern "C"
-void inc_global() {
- global++;
-}
-
-void *global_poller(void *arg) {
- while (true) {
- if (global != 42)
- break;
- usleep(100);
- }
- return 0;
-}
-
-int main(int argc, char *argv[]) {
- pthread_t p;
- pthread_create(&p, 0, global_poller, 0);
- string path = string(argv[0]) + "-so.so";
- if (0 == dlopen(path.c_str(), RTLD_NOW)) {
- fprintf(stderr, "dlerror: %s\n", dlerror());
- return 1;
- }
- pthread_join(p, 0);
- printf("PASSED\n");
- // CHECK: PASSED
- return 0;
-}
-#else // SHARED_LIB
-#include <stdio.h>
-#include <unistd.h>
-
-extern "C" void inc_global();
-
-int slow_init() {
- sleep(1);
- inc_global();
- return 42;
-}
-
-int slowly_init_glob = slow_init();
-#endif // SHARED_LIB
diff --git a/compiler-rt/test/asan/TestCases/init-order-pthread-create.cc b/compiler-rt/test/asan/TestCases/init-order-pthread-create.cc
index eeff308a4cd..b8bc93e73cf 100644
--- a/compiler-rt/test/asan/TestCases/init-order-pthread-create.cc
+++ b/compiler-rt/test/asan/TestCases/init-order-pthread-create.cc
@@ -6,25 +6,36 @@
#include <stdio.h>
#include <pthread.h>
+#include <unistd.h>
-void *run(void *arg) {
- return arg;
+void *bar(void *input, bool sleep_before_init) {
+ if (sleep_before_init)
+ usleep(500000);
+ return input;
}
-void *foo(void *input) {
- pthread_t t;
- pthread_create(&t, 0, run, input);
- void *res;
- pthread_join(t, &res);
- return res;
-}
+void *glob = bar((void*)0x1234, false);
+extern void *glob2;
-void *bar(void *input) {
- return input;
+void *poll(void *arg) {
+ void **glob = (void**)arg;
+ while (true) {
+ usleep(100000);
+ printf("glob is now: %p\n", *glob);
+ }
}
-void *glob = foo((void*)0x1234);
-extern void *glob2;
+struct GlobalPollerStarter {
+ GlobalPollerStarter() {
+ pthread_t p;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_create(&p, 0, poll, &glob);
+ pthread_attr_destroy(&attr);
+ printf("glob poller is started");
+ }
+} global_poller;
int main() {
printf("%p %p\n", glob, glob2);
OpenPOWER on IntegriCloud