[asan] second attempt to use TLS with fake stack. This time it looks (more) async-signal safe.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@190663 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/asan/asan_fake_stack.cc b/lib/asan/asan_fake_stack.cc
index bcaf0f4..4636650 100644
--- a/lib/asan/asan_fake_stack.cc
+++ b/lib/asan/asan_fake_stack.cc
@@ -122,6 +122,20 @@
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 *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/lib/asan/asan_fake_stack.h b/lib/asan/asan_fake_stack.h
index 62ef1d2..9f1da63 100644
--- a/lib/asan/asan_fake_stack.h
+++ b/lib/asan/asan_fake_stack.h
@@ -168,6 +168,9 @@
bool needs_gc_;
};
+FakeStack *GetTLSFakeStack();
+void SetTLSFakeStack(FakeStack *fs);
+
} // namespace __asan
#endif // ASAN_FAKE_STACK_H
diff --git a/lib/asan/asan_thread.cc b/lib/asan/asan_thread.cc
index 3912e04..322caa8 100644
--- a/lib/asan/asan_thread.cc
+++ b/lib/asan/asan_thread.cc
@@ -122,9 +122,11 @@
// 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)));
+ memory_order_relaxed)) {
+ fake_stack_ = FakeStack::Create(Log2(RoundUpToPowerOfTwo(stack_size)));
+ SetTLSFakeStack(fake_stack_);
+ return fake_stack_;
+ }
return 0;
}
diff --git a/lib/asan/asan_thread.h b/lib/asan/asan_thread.h
index 8633e5d..29e30ff 100644
--- a/lib/asan/asan_thread.h
+++ b/lib/asan/asan_thread.h
@@ -78,7 +78,10 @@
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() {