Bug 1113930 - Use the actual stack end address on x86 OSX and Android for the stack walker. r=froydnj

Also, in the unlikely case none of the supported methods is available, error
out at compile time, because it's not supposed to happen, apart if something
like what bug 989499 did happens again.
This commit is contained in:
Mike Hommey 2015-12-22 17:19:37 +09:00
parent cff9297236
commit 3dc777c558

View File

@ -57,6 +57,12 @@ static CriticalAddress gCriticalAddress;
extern MOZ_EXPORT void* __libc_stack_end; // from ld-linux.so
#endif
#ifdef ANDROID
#include <algorithm>
#include <unistd.h>
#include <pthread.h>
#endif
#if MOZ_STACKWALK_SUPPORTS_MACOSX
#include <pthread.h>
#include <sys/errno.h>
@ -901,8 +907,35 @@ MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
void* stackEnd;
#if HAVE___LIBC_STACK_END
stackEnd = __libc_stack_end;
#elif defined(XP_DARWIN)
stackEnd = pthread_get_stackaddr_np(pthread_self());
#elif defined(ANDROID)
pthread_attr_t sattr;
pthread_attr_init(&sattr);
pthread_getattr_np(pthread_self(), &sattr);
void* stackBase = stackEnd = nullptr;
size_t stackSize = 0;
if (gettid() != getpid()) {
// bionic's pthread_attr_getstack doesn't tell the truth for the main
// thread (see bug 846670). So don't use it for the main thread.
if (!pthread_attr_getstack(&sattr, &stackBase, &stackSize)) {
stackEnd = static_cast<char*>(stackBase) + stackSize;
} else {
stackEnd = nullptr;
}
}
if (!stackEnd) {
// So consider the current frame pointer + an arbitrary size of 8MB
// (modulo overflow ; not really arbitrary as it's the default stack
// size for the main thread) if pthread_attr_getstack failed for
// some reason (or was skipped).
static const uintptr_t kMaxStackSize = 8 * 1024 * 1024;
uintptr_t maxStackStart = uintptr_t(-1) - kMaxStackSize;
uintptr_t stackStart = std::max(maxStackStart, uintptr_t(bp));
stackEnd = reinterpret_cast<void*>(stackStart + kMaxStackSize);
}
#else
stackEnd = reinterpret_cast<void*>(-1);
# error Unsupported configuration
#endif
return FramePointerStackWalk(aCallback, aSkipFrames, aMaxFrames,
aClosure, bp, stackEnd);