From 43c4493b44e773702a8b9780a1dbc2ebdde5c080 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Fri, 13 Sep 2013 06:32:26 +0000 Subject: [PATCH] [asan] second attempt to use TLS with fake stack. This time it looks (more) async-signal safe. llvm-svn: 190663 --- compiler-rt/lib/asan/asan_fake_stack.cc | 23 ++++++++++++++++------- compiler-rt/lib/asan/asan_fake_stack.h | 3 +++ compiler-rt/lib/asan/asan_thread.cc | 8 +++++--- compiler-rt/lib/asan/asan_thread.h | 5 ++++- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/compiler-rt/lib/asan/asan_fake_stack.cc b/compiler-rt/lib/asan/asan_fake_stack.cc index bcaf0f454ce7..46366501287e 100644 --- a/compiler-rt/lib/asan/asan_fake_stack.cc +++ b/compiler-rt/lib/asan/asan_fake_stack.cc @@ -122,6 +122,20 @@ NOINLINE void FakeStack::GC(uptr real_stack) { needs_gc_ = false; } +#if SANITIZER_LINUX +static THREADLOCAL FakeStack *fake_stack_tls; + +FakeStack *GetTLSFakeStack() { + return fake_stack_tls; +} +void SetTLSFakeStack(FakeStack *fs) { + fake_stack_tls = fs; +} +#else +FakeStack *GetTLSFakeStack() { return 0; } +void SetTLSFakeStack(FakeStack *fs) { } +#endif // SANITIZER_LINUX + static FakeStack *GetFakeStack() { AsanThread *t = GetCurrentThread(); if (!t) return 0; @@ -129,14 +143,9 @@ static FakeStack *GetFakeStack() { } static FakeStack *GetFakeStackFast() { -#if 0 && SANITIZER_LINUX // breaks with signals... - static THREADLOCAL FakeStack *fake_stack; - if (!fake_stack) - fake_stack = GetFakeStack(); - return fake_stack; -#else + if (FakeStack *fs = GetTLSFakeStack()) + return fs; return GetFakeStack(); -#endif } ALWAYS_INLINE uptr OnMalloc(uptr class_id, uptr size, uptr real_stack) { diff --git a/compiler-rt/lib/asan/asan_fake_stack.h b/compiler-rt/lib/asan/asan_fake_stack.h index 62ef1d293add..9f1da63609fd 100644 --- a/compiler-rt/lib/asan/asan_fake_stack.h +++ b/compiler-rt/lib/asan/asan_fake_stack.h @@ -168,6 +168,9 @@ class FakeStack { bool needs_gc_; }; +FakeStack *GetTLSFakeStack(); +void SetTLSFakeStack(FakeStack *fs); + } // namespace __asan #endif // ASAN_FAKE_STACK_H diff --git a/compiler-rt/lib/asan/asan_thread.cc b/compiler-rt/lib/asan/asan_thread.cc index 3912e049977e..322caa8ac1c7 100644 --- a/compiler-rt/lib/asan/asan_thread.cc +++ b/compiler-rt/lib/asan/asan_thread.cc @@ -122,9 +122,11 @@ FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() { // if that was successfull, it initilizes the pointer. if (atomic_compare_exchange_strong( reinterpret_cast(&fake_stack_), &old_val, 1UL, - memory_order_relaxed)) - return fake_stack_ = - FakeStack::Create(Log2(RoundUpToPowerOfTwo(stack_size))); + memory_order_relaxed)) { + fake_stack_ = FakeStack::Create(Log2(RoundUpToPowerOfTwo(stack_size))); + SetTLSFakeStack(fake_stack_); + return fake_stack_; + } return 0; } diff --git a/compiler-rt/lib/asan/asan_thread.h b/compiler-rt/lib/asan/asan_thread.h index 8633e5dba1f0..29e30ffb353d 100644 --- a/compiler-rt/lib/asan/asan_thread.h +++ b/compiler-rt/lib/asan/asan_thread.h @@ -78,7 +78,10 @@ class AsanThread { void DeleteFakeStack() { if (!fake_stack_) return; fake_stack_->PoisonAll(0); - fake_stack_->Destroy(); + FakeStack *t = fake_stack_; + fake_stack_ = 0; + SetTLSFakeStack(0); + t->Destroy(); } bool has_fake_stack() {