From 0352a641a9e4404c6ef2aeea6a86d7ef5e862088 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 22 Dec 2015 17:19:37 +0900 Subject: [PATCH] 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. --- mozglue/misc/StackWalk.cpp | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/mozglue/misc/StackWalk.cpp b/mozglue/misc/StackWalk.cpp index aa752c424b8..7e54588c620 100644 --- a/mozglue/misc/StackWalk.cpp +++ b/mozglue/misc/StackWalk.cpp @@ -57,6 +57,12 @@ static CriticalAddress gCriticalAddress; extern MOZ_EXPORT void* __libc_stack_end; // from ld-linux.so #endif +#ifdef ANDROID +#include +#include +#include +#endif + #if MOZ_STACKWALK_SUPPORTS_MACOSX #include #include @@ -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(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(stackStart + kMaxStackSize); + } #else - stackEnd = reinterpret_cast(-1); +# error Unsupported configuration #endif return FramePointerStackWalk(aCallback, aSkipFrames, aMaxFrames, aClosure, bp, stackEnd);