Skip to content

Commit 9567b33

Browse files
authored
[asan] Switch initialization to "double-checked locking"
This allows to remove `asan_init_is_running` which likely had a data race. Simplifies #74086 and reduces a difference between platforms. Reviewers: zacklj89, eugenis, dvyukov Reviewed By: zacklj89, dvyukov Pull Request: #74387
1 parent 8227072 commit 9567b33

File tree

1 file changed

+25
-24
lines changed

1 file changed

+25
-24
lines changed

compiler-rt/lib/asan/asan_rtl.cpp

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,16 @@ static void CheckUnwind() {
7171
}
7272

7373
// -------------------------- Globals --------------------- {{{1
74-
static int asan_inited = 0;
75-
static int asan_init_is_running = 0;
74+
static StaticSpinMutex asan_inited_mutex;
75+
static atomic_uint8_t asan_inited = {0};
7676

77-
static void SetAsanInited() { asan_inited = 1; }
78-
79-
static void SetAsanInitIsRunning(u32 val) { asan_init_is_running = val; }
80-
81-
bool AsanInited() { return asan_inited == 1; }
77+
static void SetAsanInited() {
78+
atomic_store(&asan_inited, 1, memory_order_release);
79+
}
8280

83-
static bool AsanInitIsRunning() { return asan_init_is_running == 1; }
81+
bool AsanInited() {
82+
return atomic_load(&asan_inited, memory_order_acquire) == 1;
83+
}
8484

8585
bool replace_intrin_cached;
8686

@@ -390,12 +390,10 @@ void PrintAddressSpaceLayout() {
390390
kHighShadowBeg > kMidMemEnd);
391391
}
392392

393-
static void AsanInitInternal() {
393+
static bool AsanInitInternal() {
394394
if (LIKELY(AsanInited()))
395-
return;
395+
return true;
396396
SanitizerToolName = "AddressSanitizer";
397-
CHECK(!AsanInitIsRunning() && "ASan init calls itself!");
398-
SetAsanInitIsRunning(1);
399397

400398
CacheBinaryName();
401399

@@ -408,9 +406,8 @@ static void AsanInitInternal() {
408406
// Stop performing init at this point if we are being loaded via
409407
// dlopen() and the platform supports it.
410408
if (SANITIZER_SUPPORTS_INIT_FOR_DLOPEN && UNLIKELY(HandleDlopenInit())) {
411-
SetAsanInitIsRunning(0);
412409
VReport(1, "AddressSanitizer init is being performed for dlopen().\n");
413-
return;
410+
return false;
414411
}
415412

416413
AsanCheckIncompatibleRT();
@@ -471,7 +468,6 @@ static void AsanInitInternal() {
471468
// should be set to 1 prior to initializing the threads.
472469
replace_intrin_cached = flags()->replace_intrin;
473470
SetAsanInited();
474-
SetAsanInitIsRunning(0);
475471

476472
if (flags()->atexit)
477473
Atexit(asan_atexit);
@@ -515,22 +511,27 @@ static void AsanInitInternal() {
515511
VReport(1, "AddressSanitizer Init done\n");
516512

517513
WaitForDebugger(flags()->sleep_after_init, "after init");
514+
515+
return true;
518516
}
519517

520518
// Initialize as requested from some part of ASan runtime library (interceptors,
521519
// allocator, etc).
522520
void AsanInitFromRtl() {
523-
CHECK(!AsanInitIsRunning());
524-
if (UNLIKELY(!AsanInited()))
525-
AsanInitInternal();
521+
if (LIKELY(AsanInited()))
522+
return;
523+
SpinMutexLock lock(&asan_inited_mutex);
524+
AsanInitInternal();
526525
}
527526

528527
bool TryAsanInitFromRtl() {
529-
if (UNLIKELY(AsanInitIsRunning()))
528+
if (LIKELY(AsanInited()))
529+
return true;
530+
if (!asan_inited_mutex.TryLock())
530531
return false;
531-
if (UNLIKELY(!AsanInited()))
532-
AsanInitInternal();
533-
return true;
532+
bool result = AsanInitInternal();
533+
asan_inited_mutex.Unlock();
534+
return result;
534535
}
535536

536537
#if ASAN_DYNAMIC
@@ -603,7 +604,7 @@ static void UnpoisonFakeStack() {
603604
using namespace __asan;
604605

605606
void NOINLINE __asan_handle_no_return() {
606-
if (AsanInitIsRunning())
607+
if (UNLIKELY(!AsanInited()))
607608
return;
608609

609610
if (!PlatformUnpoisonStacks())
@@ -633,7 +634,7 @@ void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
633634
// We use this call as a trigger to wake up ASan from deactivated state.
634635
void __asan_init() {
635636
AsanActivate();
636-
AsanInitInternal();
637+
AsanInitFromRtl();
637638
}
638639

639640
void __asan_version_mismatch_check() {

0 commit comments

Comments
 (0)