[compiler-rt] r191510 - [asan] introduce run-time flag uar_stack_size_log to control the size of FakeStack; don't crash when the fake stack is exhausted, move some code to .cc file
Kostya Serebryany
kcc at google.com
Fri Sep 27 04:37:23 PDT 2013
Author: kcc
Date: Fri Sep 27 06:37:23 2013
New Revision: 191510
URL: http://llvm.org/viewvc/llvm-project?rev=191510&view=rev
Log:
[asan] introduce run-time flag uar_stack_size_log to control the size of FakeStack; don't crash when the fake stack is exhausted, move some code to .cc file
Modified:
compiler-rt/trunk/lib/asan/asan_fake_stack.cc
compiler-rt/trunk/lib/asan/asan_fake_stack.h
compiler-rt/trunk/lib/asan/asan_flags.h
compiler-rt/trunk/lib/asan/asan_rtl.cc
compiler-rt/trunk/lib/asan/asan_thread.cc
compiler-rt/trunk/lib/asan/lit_tests/TestCases/stack-use-after-return.cc
compiler-rt/trunk/lib/asan/tests/asan_fake_stack_test.cc
Modified: compiler-rt/trunk/lib/asan/asan_fake_stack.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_fake_stack.cc?rev=191510&r1=191509&r2=191510&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_fake_stack.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_fake_stack.cc Fri Sep 27 06:37:23 2013
@@ -35,6 +35,30 @@ ALWAYS_INLINE void SetShadow(uptr ptr, u
}
}
+FakeStack *FakeStack::Create(uptr stack_size_log) {
+ static uptr kMinStackSizeLog = 16;
+ static uptr kMaxStackSizeLog = FIRST_32_SECOND_64(24, 28);
+ if (stack_size_log < kMinStackSizeLog)
+ stack_size_log = kMinStackSizeLog;
+ if (stack_size_log > kMaxStackSizeLog)
+ stack_size_log = kMaxStackSizeLog;
+ FakeStack *res = reinterpret_cast<FakeStack *>(
+ MmapOrDie(RequiredSize(stack_size_log), "FakeStack"));
+ res->stack_size_log_ = stack_size_log;
+ if (flags()->verbosity) {
+ u8 *p = reinterpret_cast<u8 *>(res);
+ Report("T%d: FakeStack created: %p -- %p stack_size_log: %zd \n",
+ GetCurrentTidOrInvalid(), p,
+ p + FakeStack::RequiredSize(stack_size_log), stack_size_log);
+ }
+ return res;
+}
+
+void FakeStack::Destroy() {
+ PoisonAll(0);
+ UnmapOrDie(this, RequiredSize(stack_size_log_));
+}
+
void FakeStack::PoisonAll(u8 magic) {
PoisonShadow(reinterpret_cast<uptr>(this), RequiredSize(stack_size_log()),
magic);
@@ -66,8 +90,7 @@ FakeFrame *FakeStack::Allocate(uptr stac
*SavedFlagPtr(reinterpret_cast<uptr>(res), class_id) = &flags[pos];
return res;
}
- CHECK(0 && "Failed to allocate a fake stack frame");
- return 0;
+ return 0; // We are out of fake stack.
}
uptr FakeStack::AddrIsInFakeStack(uptr ptr) {
@@ -143,6 +166,8 @@ ALWAYS_INLINE uptr OnMalloc(uptr class_i
FakeStack *fs = GetFakeStackFast();
if (!fs) return real_stack;
FakeFrame *ff = fs->Allocate(fs->stack_size_log(), class_id, real_stack);
+ if (!ff)
+ return real_stack; // Out of fake stack, return the real one.
uptr ptr = reinterpret_cast<uptr>(ff);
SetShadow(ptr, size, class_id, 0);
return ptr;
Modified: compiler-rt/trunk/lib/asan/asan_fake_stack.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_fake_stack.h?rev=191510&r1=191509&r2=191510&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_fake_stack.h (original)
+++ compiler-rt/trunk/lib/asan/asan_fake_stack.h Fri Sep 27 06:37:23 2013
@@ -63,23 +63,9 @@ class FakeStack {
kMaxStackFrameSizeLog - kMinStackFrameSizeLog + 1;
// CTOR: create the FakeStack as a single mmap-ed object.
- static FakeStack *Create(uptr stack_size_log) {
- static uptr kMinStackSizeLog = 16;
- static uptr kMaxStackSizeLog = FIRST_32_SECOND_64(23, 26);
- if (stack_size_log < kMinStackSizeLog)
- stack_size_log = kMinStackSizeLog;
- if (stack_size_log > kMaxStackSizeLog)
- stack_size_log = kMaxStackSizeLog;
- FakeStack *res = reinterpret_cast<FakeStack *>(
- MmapOrDie(RequiredSize(stack_size_log), "FakeStack"));
- res->stack_size_log_ = stack_size_log;
- return res;
- }
+ static FakeStack *Create(uptr stack_size_log);
- void Destroy() {
- PoisonAll(0);
- UnmapOrDie(this, RequiredSize(stack_size_log_));
- }
+ void Destroy();
// stack_size_log is at least 15 (stack_size >= 32K).
static uptr SizeRequiredForFlags(uptr stack_size_log) {
Modified: compiler-rt/trunk/lib/asan/asan_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_flags.h?rev=191510&r1=191509&r2=191510&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_flags.h (original)
+++ compiler-rt/trunk/lib/asan/asan_flags.h Fri Sep 27 06:37:23 2013
@@ -54,6 +54,8 @@ struct Flags {
bool mac_ignore_invalid_free;
// Enables stack-use-after-return checking at run-time.
bool detect_stack_use_after_return;
+ // The minimal fake stack size log.
+ int uar_stack_size_log;
// ASan allocator flag. max_malloc_fill_size is the maximal amount of bytes
// that will be filled with malloc_fill_byte on malloc.
int max_malloc_fill_size, malloc_fill_byte;
Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=191510&r1=191509&r2=191510&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Fri Sep 27 06:37:23 2013
@@ -106,6 +106,7 @@ static void ParseFlagsFromString(Flags *
ParseFlag(str, &f->mac_ignore_invalid_free, "mac_ignore_invalid_free");
ParseFlag(str, &f->detect_stack_use_after_return,
"detect_stack_use_after_return");
+ ParseFlag(str, &f->uar_stack_size_log, "uar_stack_size_log");
ParseFlag(str, &f->max_malloc_fill_size, "max_malloc_fill_size");
ParseFlag(str, &f->malloc_fill_byte, "malloc_fill_byte");
ParseFlag(str, &f->exitcode, "exitcode");
@@ -154,6 +155,7 @@ void InitializeFlags(Flags *f, const cha
f->replace_intrin = true;
f->mac_ignore_invalid_free = false;
f->detect_stack_use_after_return = false; // Also needs the compiler flag.
+ f->uar_stack_size_log = 0;
f->max_malloc_fill_size = 0x1000; // By default, fill only the first 4K.
f->malloc_fill_byte = 0xbe;
f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE;
Modified: compiler-rt/trunk/lib/asan/asan_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread.cc?rev=191510&r1=191509&r2=191510&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_thread.cc Fri Sep 27 06:37:23 2013
@@ -124,13 +124,10 @@ FakeStack *AsanThread::AsyncSignalSafeLa
reinterpret_cast<atomic_uintptr_t *>(&fake_stack_), &old_val, 1UL,
memory_order_relaxed)) {
uptr stack_size_log = Log2(RoundUpToPowerOfTwo(stack_size));
+ if (flags()->uar_stack_size_log)
+ stack_size_log = static_cast<uptr>(flags()->uar_stack_size_log);
fake_stack_ = FakeStack::Create(stack_size_log);
SetTLSFakeStack(fake_stack_);
- if (flags()->verbosity) {
- u8 *p = reinterpret_cast<u8 *>(fake_stack_);
- Report("T%d: FakeStack created: %p -- %p\n", tid(), p,
- p + FakeStack::RequiredSize(stack_size_log));
- }
return fake_stack_;
}
return 0;
Modified: compiler-rt/trunk/lib/asan/lit_tests/TestCases/stack-use-after-return.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/TestCases/stack-use-after-return.cc?rev=191510&r1=191509&r2=191510&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/TestCases/stack-use-after-return.cc (original)
+++ compiler-rt/trunk/lib/asan/lit_tests/TestCases/stack-use-after-return.cc Fri Sep 27 06:37:23 2013
@@ -15,6 +15,11 @@
// Test that we can find UAR in a thread other than main:
// RUN: %clangxx_asan -DUseThread -O2 %s -o %t && \
// RUN: not %t 2>&1 | FileCheck --check-prefix=THREAD %s
+//
+// Test the uar_stack_size_log flag.
+//
+// RUN: ASAN_OPTIONS=$ASAN_OPTIONS:uar_stack_size_log=20:verbosity=1 not %t 2>&1 | FileCheck --check-prefix=CHECK-20 %s
+// RUN: ASAN_OPTIONS=$ASAN_OPTIONS:uar_stack_size_log=24:verbosity=1 not %t 2>&1 | FileCheck --check-prefix=CHECK-24 %s
#include <stdio.h>
#include <pthread.h>
@@ -51,6 +56,8 @@ void Func2(char *x) {
// THREAD: #0{{.*}}Func2{{.*}}stack-use-after-return.cc:[[@LINE-6]]
// THREAD: is located in stack of thread T{{[1-9]}} at offset
// THREAD: 'local' <== Memory access at offset 32 is inside this variable
+ // CHECK-20: T0: FakeStack created:{{.*}} stack_size_log: 20
+ // CHECK-24: T0: FakeStack created:{{.*}} stack_size_log: 24
}
void *Thread(void *unused) {
Modified: compiler-rt/trunk/lib/asan/tests/asan_fake_stack_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_fake_stack_test.cc?rev=191510&r1=191509&r2=191510&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_fake_stack_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_fake_stack_test.cc Fri Sep 27 06:37:23 2013
@@ -119,12 +119,8 @@ TEST(FakeStack, Allocate) {
EXPECT_EQ(x, fs->AddrIsInFakeStack(x + bytes_in_class - 1));
EXPECT_NE(x, fs->AddrIsInFakeStack(x + bytes_in_class));
}
- if (iter == 0 &&
- (cid == 0 || cid == FakeStack::kNumberOfSizeClasses - 1)) {
- // This is slow, so we do it only sometimes.
- EXPECT_DEATH(fs->Allocate(stack_size_log, cid, 0),
- "Failed to allocate a fake stack frame");
- }
+ // We are out of fake stack, so Allocate should return 0.
+ EXPECT_EQ(0UL, fs->Allocate(stack_size_log, cid, 0));
}
for (std::map<FakeFrame *, uptr>::iterator it = s.begin(); it != s.end();
++it) {
More information about the llvm-commits
mailing list