[asan] hopefully make the FakeStack async-signal safe, enable the related test
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@190592 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/asan/asan_thread.cc b/lib/asan/asan_thread.cc
index 64d07ca..5bea433 100644
--- a/lib/asan/asan_thread.cc
+++ b/lib/asan/asan_thread.cc
@@ -107,6 +107,27 @@
UnmapOrDie(this, size);
}
+// We want to create the FakeStack lazyly on the first use, but not eralier
+// than the stack size is known and the procedure has to be async-signal safe.
+FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
+ uptr stack_size = this->stack_size();
+ if (stack_size == 0) // stack_size is not yet available, don't use FakeStack.
+ return 0;
+ uptr old_val = 0;
+ // fake_stack_ has 3 states:
+ // 0 -- not initialized
+ // 1 -- being initialized
+ // ptr -- initialized
+ // This CAS checks if the state was 0 and if so changes it to state 1,
+ // if that was successfull, it initilizes the pointer.
+ if (atomic_compare_exchange_strong(
+ reinterpret_cast<atomic_uintptr_t *>(&fake_stack_), &old_val, 1UL,
+ memory_order_relaxed))
+ return fake_stack_ =
+ FakeStack::Create(Log2(RoundUpToPowerOfTwo(stack_size)));
+ return 0;
+}
+
void AsanThread::Init() {
SetThreadStackAndTls();
CHECK(AddrIsInMem(stack_bottom_));