author | Jim Chen <nchen@mozilla.com> |
Fri, 18 Sep 2015 09:17:10 -0400 | |
changeset 263241 | 5e86358d4ec223fbaa00177add41c9f33055f827 |
parent 263240 | b2956e60f8255e24a0f5686f19d6cefae382abf4 |
child 263242 | 007b7970b6c8e67cdfe88e0a1f75f9e7b6735ce6 |
push id | 29392 |
push user | kwierso@gmail.com |
push date | Fri, 18 Sep 2015 20:48:57 +0000 |
treeherder | mozilla-central@eb30e5ee32f0 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nfroyd, snorp |
bugs | 1196381, 1069556 |
milestone | 43.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
xpcom/threads/ThreadStackHelper.cpp | file | annotate | diff | comparison | revisions | |
xpcom/threads/ThreadStackHelper.h | file | annotate | diff | comparison | revisions |
--- a/xpcom/threads/ThreadStackHelper.cpp +++ b/xpcom/threads/ThreadStackHelper.cpp @@ -17,32 +17,16 @@ #include "mozilla/Attributes.h" #include "mozilla/IntegerPrintfMacros.h" #include "mozilla/Move.h" #include "mozilla/Scoped.h" #include "mozilla/UniquePtr.h" #include "mozilla/MemoryChecking.h" #include "mozilla/Snprintf.h" -#ifdef MOZ_THREADSTACKHELPER_NATIVE -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/basic_code_module.h" -#include "processor/basic_code_modules.h" -#endif - -#if defined(MOZ_THREADSTACKHELPER_X86) -#include "processor/stackwalker_x86.h" -#elif defined(MOZ_THREADSTACKHELPER_X64) -#include "processor/stackwalker_amd64.h" -#elif defined(MOZ_THREADSTACKHELPER_ARM) -#include "processor/stackwalker_arm.h" -#endif - #if defined(MOZ_VALGRIND) # include <valgrind/valgrind.h> #endif #include <string.h> #include <vector> #include <cstdlib> @@ -282,77 +266,22 @@ ThreadStackHelper::GetStack(Stack& aStac FillThreadContext(); MOZ_ALWAYS_TRUE(::thread_resume(mThreadID) == KERN_SUCCESS); #endif } #ifdef MOZ_THREADSTACKHELPER_NATIVE -class ThreadStackHelper::CodeModulesProvider - : public google_breakpad::CodeModules -{ -private: - typedef google_breakpad::CodeModule CodeModule; - typedef google_breakpad::BasicCodeModule BasicCodeModule; - - const SharedLibraryInfo mLibs; - mutable ScopedDeletePtr<BasicCodeModule> mModule; - -public: - CodeModulesProvider() : mLibs(SharedLibraryInfo::GetInfoForSelf()) {} - virtual ~CodeModulesProvider() {} - - virtual unsigned int module_count() const - { - return mLibs.GetSize(); - } - - virtual const CodeModule* GetModuleForAddress(uint64_t aAddress) const - { - MOZ_CRASH("Not implemented"); - } - - virtual const CodeModule* GetMainModule() const - { - return nullptr; - } - - virtual const CodeModule* GetModuleAtSequence(unsigned int aSequence) const - { - MOZ_CRASH("Not implemented"); - } - - virtual const CodeModule* GetModuleAtIndex(unsigned int aIndex) const - { - const SharedLibrary& lib = mLibs.GetEntry(aIndex); - mModule = new BasicCodeModule(lib.GetStart(), lib.GetEnd() - lib.GetStart(), - lib.GetName(), lib.GetBreakpadId(), - lib.GetName(), lib.GetBreakpadId(), ""); - // Keep mModule valid until the next GetModuleAtIndex call. - return mModule; - } - - virtual const CodeModules* Copy() const - { - MOZ_CRASH("Not implemented"); - } -}; - class ThreadStackHelper::ThreadContext final - : public google_breakpad::MemoryRegion { public: -#if defined(MOZ_THREADSTACKHELPER_X86) - typedef MDRawContextX86 Context; -#elif defined(MOZ_THREADSTACKHELPER_X64) - typedef MDRawContextAMD64 Context; -#elif defined(MOZ_THREADSTACKHELPER_ARM) - typedef MDRawContextARM Context; -#endif + // TODO: provide per-platform definition of Context. + typedef struct {} Context; + // Limit copied stack to 4kB static const size_t kMaxStackSize = 0x1000; // Limit unwound stack to 32 frames static const unsigned int kMaxStackFrames = 32; // Whether this structure contains valid data bool mValid; // Processor context Context mContext; @@ -365,121 +294,33 @@ public: // End of stack area const void* mStackEnd; ThreadContext() : mValid(false) , mStackBase(0) , mStackSize(0) , mStackEnd(nullptr) {} - virtual ~ThreadContext() {} - - virtual uint64_t GetBase() const { return uint64_t(mStackBase); } - virtual uint32_t GetSize() const { return mStackSize; } - virtual bool GetMemoryAtAddress(uint64_t aAddress, uint8_t* aValue) const - { - return GetMemoryAtAddressInternal(aAddress, aValue); - } - virtual bool GetMemoryAtAddress(uint64_t aAddress, uint16_t* aValue) const - { - return GetMemoryAtAddressInternal(aAddress, aValue); - } - virtual bool GetMemoryAtAddress(uint64_t aAddress, uint32_t* aValue) const - { - return GetMemoryAtAddressInternal(aAddress, aValue); - } - virtual bool GetMemoryAtAddress(uint64_t aAddress, uint64_t* aValue) const - { - return GetMemoryAtAddressInternal(aAddress, aValue); - } - -private: - template<typename T> - bool GetMemoryAtAddressInternal(uint64_t aAddress, T* aValue) const - { - const intptr_t offset = intptr_t(aAddress) - intptr_t(GetBase()); - if (offset < 0 || uintptr_t(offset) > (GetSize() - sizeof(T))) { - return false; - } - *aValue = *reinterpret_cast<const T*>(&mStack[offset]); - return true; - } }; #endif // MOZ_THREADSTACKHELPER_NATIVE void ThreadStackHelper::GetNativeStack(Stack& aStack) { #ifdef MOZ_THREADSTACKHELPER_NATIVE ThreadContext context; context.mStack = MakeUnique<uint8_t[]>(ThreadContext::kMaxStackSize); ScopedSetPtr<ThreadContext> contextPtr(mContextToFill, &context); // Get pseudostack first and fill the thread context. GetStack(aStack); NS_ENSURE_TRUE_VOID(context.mValid); - CodeModulesProvider modulesProvider; - google_breakpad::BasicCodeModules modules(&modulesProvider); - google_breakpad::BasicSourceLineResolver resolver; - google_breakpad::StackFrameSymbolizer symbolizer(nullptr, &resolver); - -#if defined(MOZ_THREADSTACKHELPER_X86) - google_breakpad::StackwalkerX86 stackWalker( - nullptr, &context.mContext, &context, &modules, &symbolizer); -#elif defined(MOZ_THREADSTACKHELPER_X64) - google_breakpad::StackwalkerAMD64 stackWalker( - nullptr, &context.mContext, &context, &modules, &symbolizer); -#elif defined(MOZ_THREADSTACKHELPER_ARM) - google_breakpad::StackwalkerARM stackWalker( - nullptr, &context.mContext, -1, &context, &modules, &symbolizer); -#else - #error "Unsupported architecture" -#endif - - google_breakpad::CallStack callStack; - std::vector<const google_breakpad::CodeModule*> modules_without_symbols; - - google_breakpad::Stackwalker::set_max_frames(ThreadContext::kMaxStackFrames); - google_breakpad::Stackwalker:: - set_max_frames_scanned(ThreadContext::kMaxStackFrames); - - NS_ENSURE_TRUE_VOID(stackWalker.Walk(&callStack, &modules_without_symbols)); - - const std::vector<google_breakpad::StackFrame*>& frames(*callStack.frames()); - for (intptr_t i = frames.size() - 1; i >= 0; i--) { - const google_breakpad::StackFrame& frame = *frames[i]; - if (!frame.module) { - continue; - } - const string& module = frame.module->code_file(); -#if defined(XP_LINUX) || defined(XP_MACOSX) - const char PATH_SEP = '/'; -#elif defined(XP_WIN) - const char PATH_SEP = '\\'; -#endif - const char* const module_basename = strrchr(module.c_str(), PATH_SEP); - const char* const module_name = module_basename ? - module_basename + 1 : module.c_str(); - - char buffer[0x100]; - size_t len = 0; - if (!frame.function_name.empty()) { - len = snprintf_literal(buffer, "%s:%s", - module_name, frame.function_name.c_str()); - } else { - len = snprintf_literal(buffer, "%s:0x%p", module_name, - (intptr_t)(frame.instruction - - frame.module->base_address())); - } - if (len) { - aStack.AppendViaBuffer(buffer, len); - } - } + // TODO: walk the saved stack frames. #endif // MOZ_THREADSTACKHELPER_NATIVE } #ifdef XP_LINUX int ThreadStackHelper::sInitialized; int ThreadStackHelper::sFillStackSignum; @@ -702,16 +543,17 @@ ThreadStackHelper::FillStackBuffer() MOZ_ASAN_BLACKLIST void ThreadStackHelper::FillThreadContext(void* aContext) { #ifdef MOZ_THREADSTACKHELPER_NATIVE if (!mContextToFill) { return; } +#if 0 // TODO: remove dependency on Breakpad structs. #if defined(XP_LINUX) const ucontext_t& context = *reinterpret_cast<ucontext_t*>(aContext); #if defined(MOZ_THREADSTACKHELPER_X86) mContextToFill->mContext.context_flags = MD_CONTEXT_X86_FULL; mContextToFill->mContext.edi = context.uc_mcontext.gregs[REG_EDI]; mContextToFill->mContext.esi = context.uc_mcontext.gregs[REG_ESI]; mContextToFill->mContext.ebx = context.uc_mcontext.gregs[REG_EBX]; mContextToFill->mContext.edx = context.uc_mcontext.gregs[REG_EDX]; @@ -859,12 +701,13 @@ ThreadStackHelper::FillThreadContext(voi for (intptr_t len = stackSize; len > 0; len -= sizeof(*src)) { *(dst++) = *(src++); } #endif mContextToFill->mStackBase = uintptr_t(sp); mContextToFill->mStackSize = stackSize; mContextToFill->mValid = true; +#endif #endif // MOZ_THREADSTACKHELPER_NATIVE } } // namespace mozilla
--- a/xpcom/threads/ThreadStackHelper.h +++ b/xpcom/threads/ThreadStackHelper.h @@ -61,17 +61,16 @@ class ThreadStackHelper public: typedef Telemetry::HangStack Stack; private: Stack* mStackToFill; #ifdef MOZ_THREADSTACKHELPER_PSEUDO const PseudoStack* const mPseudoStack; #ifdef MOZ_THREADSTACKHELPER_NATIVE - class CodeModulesProvider; class ThreadContext; // Set to non-null if GetStack should get the thread context. ThreadContext* mContextToFill; intptr_t mThreadStackBase; #endif size_t mMaxStackSize; size_t mMaxBufferSize; #endif