[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:
parent
fed077be03
commit
6a068a715d
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue