mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 19:06:44 +00:00
[Sanitizer] factor out GetThreadStackTopAndBottom from ASan runtime to common.
llvm-svn: 158140
This commit is contained in:
parent
28a9895ee0
commit
4b1f1031e6
@ -117,51 +117,6 @@ const char* AsanGetEnv(const char* name) {
|
||||
return 0; // Not found.
|
||||
}
|
||||
|
||||
void AsanThread::SetThreadStackTopAndBottom() {
|
||||
if (tid() == 0) {
|
||||
// This is the main thread. Libpthread may not be initialized yet.
|
||||
struct rlimit rl;
|
||||
CHECK(getrlimit(RLIMIT_STACK, &rl) == 0);
|
||||
|
||||
// Find the mapping that contains a stack variable.
|
||||
ProcessMaps proc_maps;
|
||||
uptr start, end, offset;
|
||||
uptr prev_end = 0;
|
||||
while (proc_maps.Next(&start, &end, &offset, 0, 0)) {
|
||||
if ((uptr)&rl < end)
|
||||
break;
|
||||
prev_end = end;
|
||||
}
|
||||
CHECK((uptr)&rl >= start && (uptr)&rl < end);
|
||||
|
||||
// Get stacksize from rlimit, but clip it so that it does not overlap
|
||||
// with other mappings.
|
||||
uptr stacksize = rl.rlim_cur;
|
||||
if (stacksize > end - prev_end)
|
||||
stacksize = end - prev_end;
|
||||
// When running with unlimited stack size, we still want to set some limit.
|
||||
// The unlimited stack size is caused by 'ulimit -s unlimited'.
|
||||
// Also, for some reason, GNU make spawns subprocesses with unlimited stack.
|
||||
if (stacksize > kMaxThreadStackSize)
|
||||
stacksize = kMaxThreadStackSize;
|
||||
stack_top_ = end;
|
||||
stack_bottom_ = end - stacksize;
|
||||
CHECK(AddrIsInStack((uptr)&rl));
|
||||
return;
|
||||
}
|
||||
pthread_attr_t attr;
|
||||
CHECK(pthread_getattr_np(pthread_self(), &attr) == 0);
|
||||
uptr stacksize = 0;
|
||||
void *stackaddr = 0;
|
||||
pthread_attr_getstack(&attr, &stackaddr, (size_t*)&stacksize);
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
stack_top_ = (uptr)stackaddr + stacksize;
|
||||
stack_bottom_ = (uptr)stackaddr;
|
||||
CHECK(stacksize < kMaxThreadStackSize); // Sanity check.
|
||||
CHECK(AddrIsInStack((uptr)&attr));
|
||||
}
|
||||
|
||||
AsanLock::AsanLock(LinkerInitialized) {
|
||||
// We assume that pthread_mutex_t initialized to all zeroes is a valid
|
||||
// unlocked mutex. We can not use PTHREAD_MUTEX_INITIALIZER as it triggers
|
||||
|
@ -132,15 +132,6 @@ const char *AsanGetEnv(const char *name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AsanThread::SetThreadStackTopAndBottom() {
|
||||
uptr stacksize = pthread_get_stacksize_np(pthread_self());
|
||||
void *stackaddr = pthread_get_stackaddr_np(pthread_self());
|
||||
stack_top_ = (uptr)stackaddr;
|
||||
stack_bottom_ = stack_top_ - stacksize;
|
||||
int local;
|
||||
CHECK(AddrIsInStack((uptr)&local));
|
||||
}
|
||||
|
||||
AsanLock::AsanLock(LinkerInitialized) {
|
||||
// We assume that OS_SPINLOCK_INIT is zero
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "asan_thread.h"
|
||||
#include "asan_thread_registry.h"
|
||||
#include "asan_mapping.h"
|
||||
#include "sanitizer_common/sanitizer_common.h"
|
||||
|
||||
namespace __asan {
|
||||
|
||||
@ -101,6 +102,12 @@ thread_return_t AsanThread::ThreadStart() {
|
||||
return res;
|
||||
}
|
||||
|
||||
void AsanThread::SetThreadStackTopAndBottom() {
|
||||
GetThreadStackTopAndBottom(tid() == 0, &stack_top_, &stack_bottom_);
|
||||
int local;
|
||||
CHECK(AddrIsInStack((uptr)&local));
|
||||
}
|
||||
|
||||
void AsanThread::ClearShadowForThreadStack() {
|
||||
PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0);
|
||||
}
|
||||
|
@ -47,17 +47,6 @@ static AsanLock dbghelp_lock(LINKER_INITIALIZED);
|
||||
static bool dbghelp_initialized = false;
|
||||
#pragma comment(lib, "dbghelp.lib")
|
||||
|
||||
void AsanThread::SetThreadStackTopAndBottom() {
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
CHECK(VirtualQuery(&mbi /* on stack */,
|
||||
&mbi, sizeof(mbi)) != 0);
|
||||
// FIXME: is it possible for the stack to not be a single allocation?
|
||||
// Are these values what ASan expects to get (reserved, not committed;
|
||||
// including stack guard page) ?
|
||||
stack_top_ = (uptr)mbi.BaseAddress + mbi.RegionSize;
|
||||
stack_bottom_ = (uptr)mbi.AllocationBase;
|
||||
}
|
||||
|
||||
void AsanStackTrace::GetStackTrace(uptr max_s, uptr pc, uptr bp) {
|
||||
max_size = max_s;
|
||||
void *tmp[kStackTraceMax];
|
||||
|
@ -26,13 +26,16 @@ const uptr kWordSizeInBits = 8 * kWordSize;
|
||||
const uptr kPageSizeBits = 12;
|
||||
const uptr kPageSize = 1UL << kPageSizeBits;
|
||||
|
||||
// Threads
|
||||
int GetPid();
|
||||
void RawWrite(const char *buffer);
|
||||
void GetThreadStackTopAndBottom(bool is_main_thread, uptr *stack_top,
|
||||
uptr *stack_bottom);
|
||||
|
||||
// Memory management
|
||||
void *MmapOrDie(uptr size, const char *mem_type);
|
||||
void UnmapOrDie(void *addr, uptr size);
|
||||
|
||||
void RawWrite(const char *buffer);
|
||||
void Printf(const char *format, ...);
|
||||
int SNPrintf(char *buffer, uptr length, const char *format, ...);
|
||||
void Report(const char *format, ...);
|
||||
|
@ -19,14 +19,18 @@
|
||||
#include "sanitizer_procmaps.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace __sanitizer {
|
||||
|
||||
// --------------- sanitizer_libc.h
|
||||
void *internal_mmap(void *addr, uptr length, int prot, int flags,
|
||||
int fd, u64 offset) {
|
||||
#if __WORDSIZE == 64
|
||||
@ -68,7 +72,55 @@ int internal_dup2(int oldfd, int newfd) {
|
||||
return syscall(__NR_dup2, oldfd, newfd);
|
||||
}
|
||||
|
||||
// ----------------- ProcessMaps implementation.
|
||||
// ----------------- sanitizer_common.h
|
||||
void GetThreadStackTopAndBottom(bool is_main_thread, uptr *stack_top,
|
||||
uptr *stack_bottom) {
|
||||
static const uptr kMaxThreadStackSize = 256 * (1 << 20); // 256M
|
||||
CHECK(stack_top);
|
||||
CHECK(stack_bottom);
|
||||
if (is_main_thread) {
|
||||
// This is the main thread. Libpthread may not be initialized yet.
|
||||
struct rlimit rl;
|
||||
CHECK(getrlimit(RLIMIT_STACK, &rl) == 0);
|
||||
|
||||
// Find the mapping that contains a stack variable.
|
||||
ProcessMaps proc_maps;
|
||||
uptr start, end, offset;
|
||||
uptr prev_end = 0;
|
||||
while (proc_maps.Next(&start, &end, &offset, 0, 0)) {
|
||||
if ((uptr)&rl < end)
|
||||
break;
|
||||
prev_end = end;
|
||||
}
|
||||
CHECK((uptr)&rl >= start && (uptr)&rl < end);
|
||||
|
||||
// Get stacksize from rlimit, but clip it so that it does not overlap
|
||||
// with other mappings.
|
||||
uptr stacksize = rl.rlim_cur;
|
||||
if (stacksize > end - prev_end)
|
||||
stacksize = end - prev_end;
|
||||
// When running with unlimited stack size, we still want to set some limit.
|
||||
// The unlimited stack size is caused by 'ulimit -s unlimited'.
|
||||
// Also, for some reason, GNU make spawns subprocesses with unlimited stack.
|
||||
if (stacksize > kMaxThreadStackSize)
|
||||
stacksize = kMaxThreadStackSize;
|
||||
*stack_top = end;
|
||||
*stack_bottom = end - stacksize;
|
||||
return;
|
||||
}
|
||||
pthread_attr_t attr;
|
||||
CHECK(pthread_getattr_np(pthread_self(), &attr) == 0);
|
||||
uptr stacksize = 0;
|
||||
void *stackaddr = 0;
|
||||
pthread_attr_getstack(&attr, &stackaddr, (size_t*)&stacksize);
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
*stack_top = (uptr)stackaddr + stacksize;
|
||||
*stack_bottom = (uptr)stackaddr;
|
||||
CHECK(stacksize < kMaxThreadStackSize); // Sanity check.
|
||||
}
|
||||
|
||||
// ----------------- sanitizer_procmaps.h
|
||||
ProcessMaps::ProcessMaps() {
|
||||
proc_self_maps_buff_len_ =
|
||||
ReadFileToBuffer("/proc/self/maps", &proc_self_maps_buff_,
|
||||
|
@ -14,20 +14,24 @@
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
#include "sanitizer_common.h"
|
||||
#include "sanitizer_internal_defs.h"
|
||||
#include "sanitizer_libc.h"
|
||||
#include "sanitizer_procmaps.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <mach-o/loader.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace __sanitizer {
|
||||
|
||||
// ---------------------- sanitizer_libc.h
|
||||
void *internal_mmap(void *addr, size_t length, int prot, int flags,
|
||||
int fd, u64 offset) {
|
||||
return mmap(addr, length, prot, flags, fd, offset);
|
||||
@ -65,7 +69,19 @@ int internal_dup2(int oldfd, int newfd) {
|
||||
return dup2(oldfd, newfd);
|
||||
}
|
||||
|
||||
// ----------------- ProcessMaps implementation.
|
||||
// ----------------- sanitizer_common.h
|
||||
void GetThreadStackTopAndBottom(bool is_main_thread, uptr *stack_top,
|
||||
uptr *stack_bottom) {
|
||||
CHECK(stack_top);
|
||||
CHECK(stack_bottom);
|
||||
uptr stacksize = pthread_get_stacksize_np(pthread_self());
|
||||
void *stackaddr = pthread_get_stackaddr_np(pthread_self());
|
||||
*stack_top = (uptr)stackaddr;
|
||||
*stack_bottom = stack_top_ - stacksize;
|
||||
}
|
||||
|
||||
|
||||
// ----------------- sanitizer_procmaps.h
|
||||
|
||||
ProcessMaps::ProcessMaps() {
|
||||
Reset();
|
||||
|
@ -19,10 +19,25 @@
|
||||
|
||||
namespace __sanitizer {
|
||||
|
||||
// --------------------- sanitizer_common.h
|
||||
int GetPid() {
|
||||
return GetProcessId(GetCurrentProcess());
|
||||
}
|
||||
|
||||
void GetThreadStackTopAndBottom(bool is_main_thread, uptr *stack_top,
|
||||
uptr *stack_bottom) {
|
||||
CHECK(stack_top);
|
||||
CHECK(stack_bottom);
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
CHECK(VirtualQuery(&mbi /* on stack */, &mbi, sizeof(mbi)) != 0);
|
||||
// FIXME: is it possible for the stack to not be a single allocation?
|
||||
// Are these values what ASan expects to get (reserved, not committed;
|
||||
// including stack guard page) ?
|
||||
*stack_top = (uptr)mbi.BaseAddress + mbi.RegionSize;
|
||||
*stack_bottom = (uptr)mbi.AllocationBase;
|
||||
}
|
||||
|
||||
|
||||
void *MmapOrDie(uptr size, const char *mem_type) {
|
||||
void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
if (rv == 0) {
|
||||
@ -41,6 +56,7 @@ void UnmapOrDie(void *addr, uptr size) {
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------ sanitizer_libc.h
|
||||
void *internal_mmap(void *addr, uptr length, int prot, int flags,
|
||||
int fd, u64 offset) {
|
||||
UNIMPLEMENTED();
|
||||
|
Loading…
x
Reference in New Issue
Block a user