[asan] add flag uar_noreserve to use noreserve mmap for fake stack. uar_noreserve=1 will save some memory but also negatively affect performance

llvm-svn: 197233
This commit is contained in:
Kostya Serebryany 2013-12-13 15:03:49 +00:00
parent a643a754be
commit 57bfdb080b
6 changed files with 34 additions and 3 deletions

View File

@ -42,13 +42,17 @@ FakeStack *FakeStack::Create(uptr stack_size_log) {
stack_size_log = kMinStackSizeLog;
if (stack_size_log > kMaxStackSizeLog)
stack_size_log = kMaxStackSizeLog;
uptr size = RequiredSize(stack_size_log);
FakeStack *res = reinterpret_cast<FakeStack *>(
MmapOrDie(RequiredSize(stack_size_log), "FakeStack"));
flags()->uar_noreserve ? MmapNoReserveOrDie(size, "FakeStack")
: MmapOrDie(size, "FakeStack"));
res->stack_size_log_ = stack_size_log;
u8 *p = reinterpret_cast<u8 *>(res);
VReport(1, "T%d: FakeStack created: %p -- %p stack_size_log: %zd \n",
VReport(1, "T%d: FakeStack created: %p -- %p stack_size_log: %zd; "
"noreserve=%d \n",
GetCurrentTidOrInvalid(), p,
p + FakeStack::RequiredSize(stack_size_log), stack_size_log);
p + FakeStack::RequiredSize(stack_size_log), stack_size_log,
flags()->uar_noreserve);
return res;
}

View File

@ -54,6 +54,8 @@ struct Flags {
bool detect_stack_use_after_return;
// The minimal fake stack size log.
int uar_stack_size_log;
// Use mmap with 'norserve' flag to allocate fake stack.
bool uar_noreserve;
// 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;

View File

@ -109,6 +109,7 @@ static void ParseFlagsFromString(Flags *f, const char *str) {
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->uar_noreserve, "uar_noreserve");
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");
@ -151,6 +152,7 @@ void InitializeFlags(Flags *f, const char *env) {
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->uar_noreserve = false;
f->max_malloc_fill_size = 0x1000; // By default, fill only the first 4K.
f->malloc_fill_byte = 0xbe;
f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE;

View File

@ -49,6 +49,7 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
void *MmapOrDie(uptr size, const char *mem_type);
void UnmapOrDie(void *addr, uptr size);
void *MmapFixedNoReserve(uptr fixed_addr, uptr size);
void *MmapNoReserveOrDie(uptr size, const char *mem_type);
void *MmapFixedOrDie(uptr fixed_addr, uptr size);
void *Mprotect(uptr fixed_addr, uptr size);
// Map aligned chunk of address space; size and alignment are powers of two.

View File

@ -80,6 +80,23 @@ void UnmapOrDie(void *addr, uptr size) {
}
}
void *MmapNoReserveOrDie(uptr size, const char *mem_type) {
uptr PageSize = GetPageSizeCached();
uptr p = internal_mmap(0,
RoundUpTo(size, PageSize),
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
-1, 0);
int reserrno;
if (internal_iserror(p, &reserrno)) {
Report("ERROR: "
"%s failed to allocate noreserve 0x%zx (%zd) bytes for '%s' (%d)\n",
SanitizerToolName, size, size, mem_type, reserrno);
CHECK("unable to mmap" && 0);
}
return (void *)p;
}
void *MmapFixedNoReserve(uptr fixed_addr, uptr size) {
uptr PageSize = GetPageSizeCached();
uptr p = internal_mmap((void*)(fixed_addr & ~(PageSize - 1)),

View File

@ -110,6 +110,11 @@ void *MmapFixedOrDie(uptr fixed_addr, uptr size) {
return MmapFixedNoReserve(fixed_addr, size);
}
void *MmapNoReserveOrDie(uptr size, const char *mem_type) {
// FIXME: make this really NoReserve?
return MmapOrDie(size, mem_type);
}
void *Mprotect(uptr fixed_addr, uptr size) {
return VirtualAlloc((LPVOID)fixed_addr, size,
MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS);