diff options
author | Kostya Serebryany <kcc@google.com> | 2012-01-05 01:07:27 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2012-01-05 01:07:27 +0000 |
commit | c549dd7b5fa5fb97270f57067797224cee0429f2 (patch) | |
tree | fee2c866d365d2ab9ecceabeb33ee2a9805352a1 /lib/asan/asan_linux.cc | |
parent | df499b44de81fc757a789878f07fcaf19ebb0016 (diff) | |
download | compiler-rt-c549dd7b5fa5fb97270f57067797224cee0429f2.tar.gz |
[asan] move {linux,mac}-specific code from asan_thread.cc to asan_{linux,mac}.cc; also add asan_procmaps.h which I forgot to add on previous commit.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@147586 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/asan/asan_linux.cc')
-rw-r--r-- | lib/asan/asan_linux.cc | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc index 2a529167d..3150f8df9 100644 --- a/lib/asan/asan_linux.cc +++ b/lib/asan/asan_linux.cc @@ -16,11 +16,15 @@ #include "asan_interceptors.h" #include "asan_internal.h" #include "asan_procmaps.h" +#include "asan_thread.h" +#include <sys/time.h> +#include <sys/resource.h> #include <sys/mman.h> #include <sys/syscall.h> #include <sys/types.h> #include <fcntl.h> +#include <pthread.h> #include <stdio.h> #include <unistd.h> @@ -150,6 +154,54 @@ bool AsanProcMaps::Next(uint64_t *start, uint64_t *end, return true; } +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. + AsanProcMaps proc_maps; + uint64_t start, end, offset; + uint64_t prev_end = 0; + while (proc_maps.Next(&start, &end, &offset, NULL, 0)) { + if ((uintptr_t)&rl < end) + break; + prev_end = end; + } + CHECK((uintptr_t)&rl >= start && (uintptr_t)&rl < end); + + // Get stacksize from rlimit, but clip it so that it does not overlap + // with other mappings. + size_t stacksize = rl.rlim_cur; + if (stacksize > end - prev_end) + stacksize = end - prev_end; + if (stacksize > kMaxThreadStackSize) + stacksize = kMaxThreadStackSize; + stack_top_ = end; + stack_bottom_ = end - stacksize; + CHECK(AddrIsInStack((uintptr_t)&rl)); + return; + } + pthread_attr_t attr; + CHECK(pthread_getattr_np(pthread_self(), &attr) == 0); + size_t stacksize = 0; + void *stackaddr = NULL; + pthread_attr_getstack(&attr, &stackaddr, &stacksize); + pthread_attr_destroy(&attr); + + stack_top_ = (uintptr_t)stackaddr + stacksize; + stack_bottom_ = (uintptr_t)stackaddr; + // 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 subrocesses with unlimited stack. + if (stacksize > kMaxThreadStackSize) { + stack_bottom_ = stack_top_ - kMaxThreadStackSize; + } + CHECK(AddrIsInStack((uintptr_t)&attr)); +} + + } // namespace __asan #endif // __linux__ |