Actually ask the pthread implementation for the stack guard size.
(cherry-pick 307091dc306c34ce9e4ee6cc3b467807b3a3bd12.)
Bug: 17111575
Change-Id: I23919b1e8aeff627a65daf57f1109bec60b196cc
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 03792b1..7d69828 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -487,11 +487,14 @@
void Thread::InitStackHwm() {
void* read_stack_base;
size_t read_stack_size;
- GetThreadStack(tlsPtr_.pthread_self, &read_stack_base, &read_stack_size);
+ size_t read_guard_size;
+ GetThreadStack(tlsPtr_.pthread_self, &read_stack_base, &read_stack_size, &read_guard_size);
- // TODO: include this in the thread dumps; potentially useful in SIGQUIT output?
- VLOG(threads) << StringPrintf("Native stack is at %p (%s)", read_stack_base,
- PrettySize(read_stack_size).c_str());
+ // This is included in the SIGQUIT output, but it's useful here for thread debugging.
+ VLOG(threads) << StringPrintf("Native stack is at %p (%s with %s guard)",
+ read_stack_base,
+ PrettySize(read_stack_size).c_str(),
+ PrettySize(read_guard_size).c_str());
tlsPtr_.stack_begin = reinterpret_cast<byte*>(read_stack_base);
tlsPtr_.stack_size = read_stack_size;
@@ -546,28 +549,13 @@
// Install the protected region if we are doing implicit overflow checks.
if (implicit_stack_check) {
- size_t guardsize;
- pthread_attr_t attributes;
- CHECK_PTHREAD_CALL(pthread_attr_init, (&attributes), "guard size query");
- CHECK_PTHREAD_CALL(pthread_attr_getguardsize, (&attributes, &guardsize), "guard size query");
- CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attributes), "guard size query");
// The thread might have protected region at the bottom. We need
// to install our own region so we need to move the limits
// of the stack to make room for it.
-#if defined(__i386__) || defined(__x86_64__)
- // Work around issue trying to read last page of stack on Intel.
- // The bug for this is b/17111575. The problem is that we are
- // unable to read the page just above the guard page on the
- // main stack on an intel target. When the bug is fixed
- // this can be removed.
- if (::art::GetTid() == getpid()) {
- guardsize += 4 * KB;
- }
-#endif
- tlsPtr_.stack_begin += guardsize + kStackOverflowProtectedSize;
- tlsPtr_.stack_end += guardsize + kStackOverflowProtectedSize;
- tlsPtr_.stack_size -= guardsize;
+ tlsPtr_.stack_begin += read_guard_size + kStackOverflowProtectedSize;
+ tlsPtr_.stack_end += read_guard_size + kStackOverflowProtectedSize;
+ tlsPtr_.stack_size -= read_guard_size;
InstallImplicitProtection();
}
diff --git a/runtime/utils.cc b/runtime/utils.cc
index d7e215b..55ecc1e 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -83,7 +83,7 @@
return result;
}
-void GetThreadStack(pthread_t thread, void** stack_base, size_t* stack_size) {
+void GetThreadStack(pthread_t thread, void** stack_base, size_t* stack_size, size_t* guard_size) {
#if defined(__APPLE__)
*stack_size = pthread_get_stacksize_np(thread);
void* stack_addr = pthread_get_stackaddr_np(thread);
@@ -96,10 +96,17 @@
} else {
*stack_base = stack_addr;
}
+
+ // This is wrong, but there doesn't seem to be a way to get the actual value on the Mac.
+ pthread_attr_t attributes;
+ CHECK_PTHREAD_CALL(pthread_attr_init, (&attributes), __FUNCTION__);
+ CHECK_PTHREAD_CALL(pthread_attr_getguardsize, (&attributes, guard_size), __FUNCTION__);
+ CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attributes), __FUNCTION__);
#else
pthread_attr_t attributes;
CHECK_PTHREAD_CALL(pthread_getattr_np, (thread, &attributes), __FUNCTION__);
CHECK_PTHREAD_CALL(pthread_attr_getstack, (&attributes, stack_base, stack_size), __FUNCTION__);
+ CHECK_PTHREAD_CALL(pthread_attr_getguardsize, (&attributes, guard_size), __FUNCTION__);
CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attributes), __FUNCTION__);
#endif
}
diff --git a/runtime/utils.h b/runtime/utils.h
index c89c41f..ad08697 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -414,7 +414,7 @@
std::string GetThreadName(pid_t tid);
// Returns details of the given thread's stack.
-void GetThreadStack(pthread_t thread, void** stack_base, size_t* stack_size);
+void GetThreadStack(pthread_t thread, void** stack_base, size_t* stack_size, size_t* guard_size);
// Reads data from "/proc/self/task/${tid}/stat".
void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu);