[compiler-rt] 20ee72d - tsan: don't call dlsym during exit
Dmitry Vyukov via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 21 22:12:04 PDT 2021
Author: Dmitry Vyukov
Date: 2021-09-22T07:11:59+02:00
New Revision: 20ee72d4ccb17c6f32641c690fa129475427ae45
URL: https://github.com/llvm/llvm-project/commit/20ee72d4ccb17c6f32641c690fa129475427ae45
DIFF: https://github.com/llvm/llvm-project/commit/20ee72d4ccb17c6f32641c690fa129475427ae45.diff
LOG: tsan: don't call dlsym during exit
dlsym calls into dynamic linker which calls malloc and other things.
It's problematic to do it during the actual exit, because
it can happen from a singal handler or from within the runtime
after we reported the first bug, etc.
See https://github.com/google/sanitizers/issues/1440 for an example
(captured in the added test).
Initialize the callbacks during startup instead.
Depends on D110159.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D110166
Added:
compiler-rt/test/tsan/signal_exit.cpp
Modified:
compiler-rt/lib/tsan/rtl/tsan_interface.h
compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp
compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
compiler-rt/lib/tsan/rtl/tsan_rtl.h
Removed:
################################################################################
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface.h b/compiler-rt/lib/tsan/rtl/tsan_interface.h
index 482da73510ef..711f064174c2 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interface.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_interface.h
@@ -417,12 +417,6 @@ SANITIZER_INTERFACE_ATTRIBUTE
void __tsan_go_atomic64_compare_exchange(ThreadState *thr, uptr cpc, uptr pc,
u8 *a);
-SANITIZER_INTERFACE_ATTRIBUTE
-void __tsan_on_initialize();
-
-SANITIZER_INTERFACE_ATTRIBUTE
-int __tsan_on_finalize(int failed);
-
} // extern "C"
} // namespace __tsan
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp
index 13d80aa79221..55c2919ca4e0 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp
@@ -14,12 +14,14 @@
#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_POSIX
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_errno.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_procmaps.h"
-#include "tsan_platform.h"
-#include "tsan_rtl.h"
+# include <dlfcn.h>
+
+# include "sanitizer_common/sanitizer_common.h"
+# include "sanitizer_common/sanitizer_errno.h"
+# include "sanitizer_common/sanitizer_libc.h"
+# include "sanitizer_common/sanitizer_procmaps.h"
+# include "tsan_platform.h"
+# include "tsan_rtl.h"
namespace __tsan {
@@ -70,6 +72,11 @@ void InitializeShadowMemory() {
meta, meta + meta_size, meta_size >> 30);
InitializeShadowMemoryPlatform();
+
+ on_initialize = reinterpret_cast<void (*)(void)>(
+ dlsym(RTLD_DEFAULT, "__tsan_on_initialize"));
+ on_finalize =
+ reinterpret_cast<int (*)(int)>(dlsym(RTLD_DEFAULT, "__tsan_on_finalize"));
}
static bool TryProtectRange(uptr beg, uptr end) {
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
index f13a05066652..12211cff1c02 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
@@ -36,6 +36,11 @@ extern "C" void __tsan_resume() {
namespace __tsan {
+#if !SANITIZER_GO
+void (*on_initialize)(void);
+int (*on_finalize)(int);
+#endif
+
#if !SANITIZER_GO && !SANITIZER_MAC
__attribute__((tls_model("initial-exec")))
THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState)] ALIGNED(64);
@@ -52,17 +57,16 @@ void OnInitialize();
SANITIZER_WEAK_CXX_DEFAULT_IMPL
bool OnFinalize(bool failed) {
#if !SANITIZER_GO
- if (auto *ptr = dlsym(RTLD_DEFAULT, "__tsan_on_finalize"))
- return reinterpret_cast<decltype(&__tsan_on_finalize)>(ptr)(failed);
+ if (on_finalize)
+ return on_finalize(failed);
#endif
return failed;
}
SANITIZER_WEAK_CXX_DEFAULT_IMPL
void OnInitialize() {
#if !SANITIZER_GO
- if (auto *ptr = dlsym(RTLD_DEFAULT, "__tsan_on_initialize")) {
- return reinterpret_cast<decltype(&__tsan_on_initialize)>(ptr)();
- }
+ if (on_initialize)
+ on_initialize();
#endif
}
#endif
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
index 1eb9b8c13823..af149460e06b 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
@@ -985,6 +985,11 @@ void TraceTime(ThreadState *thr);
} // namespace v3
+#if !SANITIZER_GO
+extern void (*on_initialize)(void);
+extern int (*on_finalize)(int);
+#endif
+
} // namespace __tsan
#endif // TSAN_RTL_H
diff --git a/compiler-rt/test/tsan/signal_exit.cpp b/compiler-rt/test/tsan/signal_exit.cpp
new file mode 100644
index 000000000000..0c4444d2c409
--- /dev/null
+++ b/compiler-rt/test/tsan/signal_exit.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include "test.h"
+#include <signal.h>
+#include <sys/types.h>
+
+static void handler(int, siginfo_t *, void *) {
+ write(2, "SIGNAL\n", 7);
+ // CHECK: SIGNAL
+ _exit(0);
+ // CHECK-NOT: ThreadSanitizer: signal-unsafe call
+}
+
+int main() {
+ struct sigaction act = {};
+ act.sa_sigaction = &handler;
+ act.sa_flags = SA_SIGINFO;
+ sigaction(SIGPROF, &act, 0);
+ raise(SIGPROF);
+ fprintf(stderr, "DONE\n");
+ // CHECK-NOT: DONE
+ return 0;
+}
More information about the llvm-commits
mailing list