[asan] second attempt to use TLS with fake stack. This time it looks (more) async-signal safe.

llvm-svn: 190663
This commit is contained in:
Kostya Serebryany 2013-09-13 06:32:26 +00:00
parent c19851ab6c
commit 43c4493b44
4 changed files with 28 additions and 11 deletions

View File

@ -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) {

View File

@ -168,6 +168,9 @@ class FakeStack {
bool needs_gc_;
};
FakeStack *GetTLSFakeStack();
void SetTLSFakeStack(FakeStack *fs);
} // namespace __asan
#endif // ASAN_FAKE_STACK_H

View File

@ -122,9 +122,11 @@ FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
// 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;
}

View File

@ -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() {