[asan] initialize fake_stack lazily and increase its maximal size. This makes -fsanitize=address,use-after-return more robust: all SPEC tests pass now. In the default mode thread stacks become a bit smaller.

llvm-svn: 184934
This commit is contained in:
Kostya Serebryany 2013-06-26 12:16:05 +00:00
parent fed077be03
commit 6a068a715d
5 changed files with 29 additions and 19 deletions

View File

@ -17,11 +17,6 @@
namespace __asan {
FakeStack::FakeStack() {
CHECK(REAL(memset));
REAL(memset)(this, 0, sizeof(*this));
}
bool FakeStack::AddrIsInSizeClass(uptr addr, uptr size_class) {
uptr mem = allocated_size_classes_[size_class];
uptr size = ClassMmapSize(size_class);
@ -170,7 +165,8 @@ uptr __asan_stack_malloc(uptr size, uptr real_stack) {
// TSD is gone, use the real stack.
return real_stack;
}
uptr ptr = t->fake_stack().AllocateStack(size, real_stack);
t->LazyInitFakeStack();
uptr ptr = t->fake_stack()->AllocateStack(size, real_stack);
// Printf("__asan_stack_malloc %p %zu %p\n", ptr, size, real_stack);
return ptr;
}

View File

@ -71,8 +71,6 @@ class FakeFrameLifo {
// call to __asan_stack_malloc.
class FakeStack {
public:
FakeStack();
explicit FakeStack(LinkerInitialized x) : call_stack_(x) {}
void Init(uptr stack_size);
void StopUsingFakeStack() { alive_ = false; }
void Cleanup();
@ -88,7 +86,7 @@ class FakeStack {
static const uptr kMaxStackMallocSize = 1 << kMaxStackFrameSizeLog;
static const uptr kNumberOfSizeClasses =
kMaxStackFrameSizeLog - kMinStackFrameSizeLog + 1;
static const uptr kMaxRecursionDepth = 1023;
static const uptr kMaxRecursionDepth = 15000;
bool AddrIsInSizeClass(uptr addr, uptr size_class);
@ -112,6 +110,8 @@ class FakeStack {
FakeFrameLifo<kMaxRecursionDepth> call_stack_;
};
COMPILER_CHECK(sizeof(FakeStack) <= (1 << 17));
} // namespace __asan
#endif // ASAN_FAKE_STACK_H

View File

@ -481,7 +481,8 @@ class ScopedInErrorReport {
// in case we call an instrumented function from a symbolizer.
AsanThread *curr_thread = GetCurrentThread();
CHECK(curr_thread);
curr_thread->fake_stack().StopUsingFakeStack();
if (curr_thread->fake_stack())
curr_thread->fake_stack()->StopUsingFakeStack();
}
}
// Destructor is NORETURN, as functions that report errors are.

View File

@ -102,7 +102,7 @@ void AsanThread::Destroy() {
// some code may still be executing in later TSD destructors
// and we don't want it to have any poisoned stack.
ClearShadowForThreadStackAndTLS();
fake_stack().Cleanup();
DeleteFakeStack();
uptr size = RoundUpTo(sizeof(AsanThread), GetPageSizeCached());
UnmapOrDie(this, size);
}
@ -118,7 +118,7 @@ void AsanThread::Init() {
tid(), (void*)stack_bottom_, (void*)stack_top_,
stack_top_ - stack_bottom_, &local);
}
fake_stack_.Init(stack_size());
fake_stack_ = 0; // Will be initialized lazily if needed.
AsanPlatformThreadInit();
}
@ -166,8 +166,8 @@ const char *AsanThread::GetFrameNameByAddr(uptr addr, uptr *offset,
uptr bottom = 0;
if (AddrIsInStack(addr)) {
bottom = stack_bottom();
} else {
bottom = fake_stack().AddrIsInFakeStack(addr);
} else if (fake_stack()) {
bottom = fake_stack()->AddrIsInFakeStack(addr);
CHECK(bottom);
*offset = addr - bottom;
*frame_pc = ((uptr*)bottom)[2];
@ -203,9 +203,11 @@ static bool ThreadStackContainsAddress(ThreadContextBase *tctx_base,
void *addr) {
AsanThreadContext *tctx = static_cast<AsanThreadContext*>(tctx_base);
AsanThread *t = tctx->thread;
return (t && t->fake_stack().StackSize() &&
(t->fake_stack().AddrIsInFakeStack((uptr)addr) ||
t->AddrIsInStack((uptr)addr)));
if (!t) return false;
if (t->AddrIsInStack((uptr)addr)) return true;
if (t->fake_stack() && t->fake_stack()->AddrIsInFakeStack((uptr)addr))
return true;
return false;
}
AsanThread *GetCurrentThread() {

View File

@ -75,7 +75,18 @@ class AsanThread {
return addr >= stack_bottom_ && addr < stack_top_;
}
FakeStack &fake_stack() { return fake_stack_; }
void LazyInitFakeStack() {
if (fake_stack_) return;
fake_stack_ = (FakeStack*)MmapOrDie(sizeof(FakeStack), "FakeStack");
fake_stack_->Init(stack_size());
}
void DeleteFakeStack() {
if (!fake_stack_) return;
fake_stack_->Cleanup();
UnmapOrDie(fake_stack_, sizeof(FakeStack));
}
FakeStack *fake_stack() { return fake_stack_; }
AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
AsanStats &stats() { return stats_; }
@ -91,7 +102,7 @@ class AsanThread {
uptr tls_begin_;
uptr tls_end_;
FakeStack fake_stack_;
FakeStack *fake_stack_;
AsanThreadLocalMallocStorage malloc_storage_;
AsanStats stats_;
};