[compiler-rt] 0a2a319 - [rtsan] Make sure rtsan gets initialized on mac (#100188)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 11 15:58:53 PDT 2024
Author: Chris Apple
Date: 2024-08-11T15:58:49-07:00
New Revision: 0a2a319ea6c8dc59fd3f0e284766361b8deca51c
URL: https://github.com/llvm/llvm-project/commit/0a2a319ea6c8dc59fd3f0e284766361b8deca51c
DIFF: https://github.com/llvm/llvm-project/commit/0a2a319ea6c8dc59fd3f0e284766361b8deca51c.diff
LOG: [rtsan] Make sure rtsan gets initialized on mac (#100188)
Intermittently on my mac I was getting the same nullptr crash in dlsym.
We need to make sure rtsan gets initialized on mac between when the
binary starts running, and the first intercepted function is called.
Until that point we should use the DlsymAllocator.
Added:
Modified:
compiler-rt/lib/rtsan/rtsan.cpp
compiler-rt/lib/rtsan/rtsan.h
compiler-rt/lib/rtsan/rtsan_interceptors.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp
index cf7fbddd9eb9c2..237475eedf5005 100644
--- a/compiler-rt/lib/rtsan/rtsan.cpp
+++ b/compiler-rt/lib/rtsan/rtsan.cpp
@@ -12,23 +12,42 @@
#include <rtsan/rtsan_context.h>
#include <rtsan/rtsan_interceptors.h>
+#include "sanitizer_common/sanitizer_atomic.h"
+#include "sanitizer_common/sanitizer_mutex.h"
+
using namespace __rtsan;
+using namespace __sanitizer;
+
+static StaticSpinMutex rtsan_inited_mutex;
+static atomic_uint8_t rtsan_initialized = {0};
-bool __rtsan::rtsan_initialized;
-bool __rtsan::rtsan_init_is_running;
+static void SetInitialized() {
+ atomic_store(&rtsan_initialized, 1, memory_order_release);
+}
extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init() {
- CHECK(!rtsan_init_is_running);
- if (rtsan_initialized)
+ CHECK(!__rtsan_is_initialized());
+ InitializeInterceptors();
+ SetInitialized();
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_ensure_initialized() {
+ if (LIKELY(__rtsan_is_initialized()))
return;
- rtsan_init_is_running = true;
- InitializeInterceptors();
+ SpinMutexLock lock(&rtsan_inited_mutex);
+
+ // Someone may have initialized us while we were waiting for the lock
+ if (__rtsan_is_initialized())
+ return;
+
+ __rtsan_init();
+}
- rtsan_init_is_running = false;
- rtsan_initialized = true;
+SANITIZER_INTERFACE_ATTRIBUTE bool __rtsan_is_initialized() {
+ return atomic_load(&rtsan_initialized, memory_order_acquire) == 1;
}
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_realtime_enter() {
diff --git a/compiler-rt/lib/rtsan/rtsan.h b/compiler-rt/lib/rtsan/rtsan.h
index ccddaf2c893efc..094c989895d22b 100644
--- a/compiler-rt/lib/rtsan/rtsan.h
+++ b/compiler-rt/lib/rtsan/rtsan.h
@@ -14,17 +14,17 @@
extern "C" {
-namespace __rtsan {
-
-extern bool rtsan_initialized;
-extern bool rtsan_init_is_running;
-
-} // namespace __rtsan
-
// Initialise rtsan interceptors.
// A call to this method is added to the preinit array on Linux systems.
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init();
+// Initializes rtsan if it has not been initialized yet.
+// Used by the RTSan runtime to ensure that rtsan is initialized before any
+// other rtsan functions are called.
+SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_ensure_initialized();
+
+SANITIZER_INTERFACE_ATTRIBUTE bool __rtsan_is_initialized();
+
// Enter real-time context.
// When in a real-time context, RTSan interceptors will error if realtime
// violations are detected. Calls to this method are injected at the code
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
index b63040446e53c7..e451ea6b03622a 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
@@ -51,16 +51,15 @@ void OSSpinLockLock(volatile OSSpinLock *__lock);
using namespace __sanitizer;
-using __rtsan::rtsan_init_is_running;
-using __rtsan::rtsan_initialized;
-
namespace {
struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
- static bool UseImpl() { return !rtsan_initialized; }
+ static bool UseImpl() { return !__rtsan_is_initialized(); }
};
} // namespace
void ExpectNotRealtime(const char *intercepted_function_name) {
+ __rtsan_ensure_initialized();
+
__rtsan::GetContextForThisThread().ExpectNotRealtime(
intercepted_function_name);
}
More information about the llvm-commits
mailing list