[compiler-rt] [asan] Switch initialization to "double-checked locking" (PR #74387)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 4 15:41:47 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: Vitaly Buka (vitalybuka)
<details>
<summary>Changes</summary>
This allows to remove `asan_init_is_running` which likely had a data
race.
---
Full diff: https://github.com/llvm/llvm-project/pull/74387.diff
1 Files Affected:
- (modified) compiler-rt/lib/asan/asan_rtl.cpp (+25-24)
``````````diff
diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp
index 04ecd20821fa6..52d3461ada6c6 100644
--- a/compiler-rt/lib/asan/asan_rtl.cpp
+++ b/compiler-rt/lib/asan/asan_rtl.cpp
@@ -71,16 +71,16 @@ static void CheckUnwind() {
}
// -------------------------- Globals --------------------- {{{1
-static int asan_inited = 0;
-static int asan_init_is_running = 0;
+static StaticSpinMutex asan_inited_mutex;
+static atomic_uint8_t asan_inited = {0};
-static void SetAsanInited() { asan_inited = 1; }
-
-static void SetAsanInitIsRunning(u32 val) { asan_init_is_running = val; }
-
-bool AsanInited() { return asan_inited == 1; }
+static void SetAsanInited() {
+ atomic_store(&asan_inited, 1, memory_order_release);
+}
-static bool AsanInitIsRunning() { return asan_init_is_running == 1; }
+bool AsanInited() {
+ return atomic_load(&asan_inited, memory_order_acquire) == 1;
+}
bool replace_intrin_cached;
@@ -390,12 +390,10 @@ void PrintAddressSpaceLayout() {
kHighShadowBeg > kMidMemEnd);
}
-static void AsanInitInternal() {
+static bool AsanInitInternal() {
if (LIKELY(AsanInited()))
- return;
+ return true;
SanitizerToolName = "AddressSanitizer";
- CHECK(!AsanInitIsRunning() && "ASan init calls itself!");
- SetAsanInitIsRunning(1);
CacheBinaryName();
@@ -408,9 +406,8 @@ static void AsanInitInternal() {
// Stop performing init at this point if we are being loaded via
// dlopen() and the platform supports it.
if (SANITIZER_SUPPORTS_INIT_FOR_DLOPEN && UNLIKELY(HandleDlopenInit())) {
- SetAsanInitIsRunning(0);
VReport(1, "AddressSanitizer init is being performed for dlopen().\n");
- return;
+ return false;
}
AsanCheckIncompatibleRT();
@@ -471,7 +468,6 @@ static void AsanInitInternal() {
// should be set to 1 prior to initializing the threads.
replace_intrin_cached = flags()->replace_intrin;
SetAsanInited();
- SetAsanInitIsRunning(0);
if (flags()->atexit)
Atexit(asan_atexit);
@@ -515,22 +511,27 @@ static void AsanInitInternal() {
VReport(1, "AddressSanitizer Init done\n");
WaitForDebugger(flags()->sleep_after_init, "after init");
+
+ return true;
}
// Initialize as requested from some part of ASan runtime library (interceptors,
// allocator, etc).
void AsanInitFromRtl() {
- CHECK(!AsanInitIsRunning());
- if (UNLIKELY(!AsanInited()))
- AsanInitInternal();
+ if (LIKELY(AsanInited()))
+ return;
+ SpinMutexLock lock(&asan_inited_mutex);
+ AsanInitInternal();
}
bool TryAsanInitFromRtl() {
- if (UNLIKELY(AsanInitIsRunning()))
+ if (LIKELY(AsanInited()))
+ return true;
+ if (!asan_inited_mutex.TryLock())
return false;
- if (UNLIKELY(!AsanInited()))
- AsanInitInternal();
- return true;
+ bool result = AsanInitInternal();
+ asan_inited_mutex.Unlock();
+ return result;
}
#if ASAN_DYNAMIC
@@ -603,7 +604,7 @@ static void UnpoisonFakeStack() {
using namespace __asan;
void NOINLINE __asan_handle_no_return() {
- if (AsanInitIsRunning())
+ if (!TryAsanInitFromRtl())
return;
if (!PlatformUnpoisonStacks())
@@ -633,7 +634,7 @@ void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
// We use this call as a trigger to wake up ASan from deactivated state.
void __asan_init() {
AsanActivate();
- AsanInitInternal();
+ AsanInitFromRtl();
}
void __asan_version_mismatch_check() {
``````````
</details>
https://github.com/llvm/llvm-project/pull/74387
More information about the llvm-commits
mailing list