diff options
author | Kostya Serebryany <kcc@google.com> | 2013-09-12 08:34:50 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2013-09-12 08:34:50 +0000 |
commit | c98fc1f8e52812cfaf5b19a29db5ed56acb0a682 (patch) | |
tree | c90e96b56b5a6a608fe37000297c40afb2bef68e /lib/asan/asan_thread.cc | |
parent | 96a575f05b2a45774170a118ea69ddae3659b645 (diff) |
[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
Diffstat (limited to 'lib/asan/asan_thread.cc')
-rw-r--r-- | lib/asan/asan_thread.cc | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/lib/asan/asan_thread.cc b/lib/asan/asan_thread.cc index 64d07ca0d..5bea433fb 100644 --- a/lib/asan/asan_thread.cc +++ b/lib/asan/asan_thread.cc @@ -107,6 +107,27 @@ void AsanThread::Destroy() { 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_)); |