[compiler-rt] [rtsan] Make sure rtsan gets initialized on mac (PR #100188)

Chris Apple via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 11 13:57:07 PDT 2024


https://github.com/cjappl updated https://github.com/llvm/llvm-project/pull/100188

>From f3fa2f3a0fd0792d85d9e8abdb2b2584b006f053 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Tue, 23 Jul 2024 13:00:02 -0700
Subject: [PATCH 1/6] Make sure rtsan gets initialized on mac

---
 compiler-rt/lib/rtsan/rtsan_interceptors.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
index b63040446e53c7..35688ac25eb138 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
@@ -51,7 +51,6 @@ void OSSpinLockLock(volatile OSSpinLock *__lock);
 
 using namespace __sanitizer;
 
-using __rtsan::rtsan_init_is_running;
 using __rtsan::rtsan_initialized;
 
 namespace {
@@ -61,6 +60,9 @@ struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
 } // namespace
 
 void ExpectNotRealtime(const char *intercepted_function_name) {
+  if (!rtsan_initialized)
+    __rtsan_init();
+
   __rtsan::GetContextForThisThread().ExpectNotRealtime(
       intercepted_function_name);
 }

>From 4a7179e03b43fba0fcc1c88ec494b7bc77564d0a Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Tue, 30 Jul 2024 12:15:13 -0700
Subject: [PATCH 2/6] [PR] move to atomic variables for initialization

---
 compiler-rt/lib/rtsan/rtsan.cpp              | 34 ++++++++++++++++----
 compiler-rt/lib/rtsan/rtsan.h                |  9 ++----
 compiler-rt/lib/rtsan/rtsan_interceptors.cpp |  6 ++--
 3 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp
index cf7fbddd9eb9c2..61884387d410cd 100644
--- a/compiler-rt/lib/rtsan/rtsan.cpp
+++ b/compiler-rt/lib/rtsan/rtsan.cpp
@@ -12,23 +12,43 @@
 #include <rtsan/rtsan_context.h>
 #include <rtsan/rtsan_interceptors.h>
 
+#include "sanitizer_common/sanitizer_atomic.h"
+
 using namespace __rtsan;
+using namespace __sanitizer;
+
+static atomic_uint8_t rtsan_initialized{0};
+static atomic_uint8_t rtsan_init_is_running{0};
+
+static void SetInitIsRunning(bool is_running) {
+  atomic_store(&rtsan_init_is_running, is_running, memory_order_release);
+}
+
+static bool IsInitRunning() {
+  return atomic_load(&rtsan_init_is_running, memory_order_acquire) == 1;
+}
 
-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(!IsInitRunning());
+  if (__rtsan_is_initialized())
     return;
-  rtsan_init_is_running = true;
+
+  SetInitIsRunning(true);
 
   InitializeInterceptors();
 
-  rtsan_init_is_running = false;
-  rtsan_initialized = true;
+  SetInitIsRunning(false);
+  SetInitialized();
+}
+
+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..9ba30b5b111e06 100644
--- a/compiler-rt/lib/rtsan/rtsan.h
+++ b/compiler-rt/lib/rtsan/rtsan.h
@@ -14,17 +14,12 @@
 
 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();
 
+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 35688ac25eb138..8ae02988a326c5 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
@@ -51,16 +51,14 @@ void OSSpinLockLock(volatile OSSpinLock *__lock);
 
 using namespace __sanitizer;
 
-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) {
-  if (!rtsan_initialized)
+  if (!__rtsan_is_initialized())
     __rtsan_init();
 
   __rtsan::GetContextForThisThread().ExpectNotRealtime(

>From e47fe6182cd357518c27eb3f2046b8e65de7903c Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Wed, 7 Aug 2024 16:18:44 -0700
Subject: [PATCH 3/6] [PR]: Introduce mutex for initalization, introduce
 _ensure_initialized

---
 compiler-rt/lib/rtsan/rtsan.cpp              | 28 +++++++++-----------
 compiler-rt/lib/rtsan/rtsan.h                |  5 ++++
 compiler-rt/lib/rtsan/rtsan_interceptors.cpp |  3 +--
 3 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp
index 61884387d410cd..d0bbaa9472c427 100644
--- a/compiler-rt/lib/rtsan/rtsan.cpp
+++ b/compiler-rt/lib/rtsan/rtsan.cpp
@@ -13,20 +13,13 @@
 #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};
-static atomic_uint8_t rtsan_init_is_running{0};
-
-static void SetInitIsRunning(bool is_running) {
-  atomic_store(&rtsan_init_is_running, is_running, memory_order_release);
-}
-
-static bool IsInitRunning() {
-  return atomic_load(&rtsan_init_is_running, memory_order_acquire) == 1;
-}
 
 static void SetInitialized() {
   atomic_store(&rtsan_initialized, 1, memory_order_release);
@@ -35,16 +28,21 @@ static void SetInitialized() {
 extern "C" {
 
 SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init() {
-  CHECK(!IsInitRunning());
-  if (__rtsan_is_initialized())
+  InitializeInterceptors();
+  SetInitialized();
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_ensure_initialized() {
+  if (LIKELY(__rtsan_is_initialized()))
     return;
 
-  SetInitIsRunning(true);
+  SpinMutexLock lock(&rtsan_inited_mutex);
 
-  InitializeInterceptors();
+  // Someone may have initialized us while we were waiting for the lock
+  if (__rtsan_is_initialized())
+    return;
 
-  SetInitIsRunning(false);
-  SetInitialized();
+  __rtsan_init();
 }
 
 SANITIZER_INTERFACE_ATTRIBUTE bool __rtsan_is_initialized() {
diff --git a/compiler-rt/lib/rtsan/rtsan.h b/compiler-rt/lib/rtsan/rtsan.h
index 9ba30b5b111e06..094c989895d22b 100644
--- a/compiler-rt/lib/rtsan/rtsan.h
+++ b/compiler-rt/lib/rtsan/rtsan.h
@@ -18,6 +18,11 @@ extern "C" {
 // 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.
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
index 8ae02988a326c5..e451ea6b03622a 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
@@ -58,8 +58,7 @@ struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
 } // namespace
 
 void ExpectNotRealtime(const char *intercepted_function_name) {
-  if (!__rtsan_is_initialized())
-    __rtsan_init();
+  __rtsan_ensure_initialized();
 
   __rtsan::GetContextForThisThread().ExpectNotRealtime(
       intercepted_function_name);

>From 45ec2291e79f76d1e96bdd3fc94713fc335b888e Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Wed, 7 Aug 2024 18:08:49 -0700
Subject: [PATCH 4/6] Assert to ensure we only initialize once

---
 compiler-rt/lib/rtsan/rtsan.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp
index d0bbaa9472c427..167fc116e69d66 100644
--- a/compiler-rt/lib/rtsan/rtsan.cpp
+++ b/compiler-rt/lib/rtsan/rtsan.cpp
@@ -25,9 +25,14 @@ static void SetInitialized() {
   atomic_store(&rtsan_initialized, 1, memory_order_release);
 }
 
+static bool IsInitialized() {
+  return atomic_load(&rtsan_initialized, memory_order_acquire) == 1;
+}
+
 extern "C" {
 
 SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init() {
+  CHECK(!IsInitialized());
   InitializeInterceptors();
   SetInitialized();
 }

>From 20e7e62354780be1f01770fbfc471d116aaa2e19 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Sun, 11 Aug 2024 13:22:26 -0700
Subject: [PATCH 5/6] [Style] fix brace initialization style to match LLVM
 recommended

---
 compiler-rt/lib/rtsan/rtsan.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp
index 167fc116e69d66..0a9e081af0336f 100644
--- a/compiler-rt/lib/rtsan/rtsan.cpp
+++ b/compiler-rt/lib/rtsan/rtsan.cpp
@@ -19,7 +19,7 @@ using namespace __rtsan;
 using namespace __sanitizer;
 
 static StaticSpinMutex rtsan_inited_mutex;
-static atomic_uint8_t rtsan_initialized{0};
+static atomic_uint8_t rtsan_initialized = {0};
 
 static void SetInitialized() {
   atomic_store(&rtsan_initialized, 1, memory_order_release);

>From d87f7dbefaebf99d77957386ffc91860a1162c67 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Sun, 11 Aug 2024 13:22:49 -0700
Subject: [PATCH 6/6] Get rid of duplicate static function for initialization

---
 compiler-rt/lib/rtsan/rtsan.cpp | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp
index 0a9e081af0336f..237475eedf5005 100644
--- a/compiler-rt/lib/rtsan/rtsan.cpp
+++ b/compiler-rt/lib/rtsan/rtsan.cpp
@@ -25,14 +25,10 @@ static void SetInitialized() {
   atomic_store(&rtsan_initialized, 1, memory_order_release);
 }
 
-static bool IsInitialized() {
-  return atomic_load(&rtsan_initialized, memory_order_acquire) == 1;
-}
-
 extern "C" {
 
 SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init() {
-  CHECK(!IsInitialized());
+  CHECK(!__rtsan_is_initialized());
   InitializeInterceptors();
   SetInitialized();
 }



More information about the llvm-commits mailing list