summaryrefslogtreecommitdiff
path: root/lib/asan/asan_linux.cc
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2012-01-05 01:07:27 +0000
committerKostya Serebryany <kcc@google.com>2012-01-05 01:07:27 +0000
commitc549dd7b5fa5fb97270f57067797224cee0429f2 (patch)
treefee2c866d365d2ab9ecceabeb33ee2a9805352a1 /lib/asan/asan_linux.cc
parentdf499b44de81fc757a789878f07fcaf19ebb0016 (diff)
downloadcompiler-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.cc52
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__