commit 8c4206f4325d87eaeb68372c462ff2749a1d82a1 Author: Jim Chen nchen@mozilla.com Date: Fri Sep 18 09:17:10 2015 -0400
Bug 1196381 - Eliminate breakpad dependency in ThreadStackHelper; r=nfroyd r=snorp The breakpad dependency in ThreadStackHelper is preventing us from upgrading our in-tree copy to a newer version (bug 1069556). This patch gets rid of that dependency. This makes native stack frames not work for BHR, but because of the ftp.m.o decommissioning, native symbolication was already broken and naive stack frames already don't work, so we don't really lose anything from this patch.
Eventually we want to make ThreadStackHelper use other means of unwinding, such as LUL for Linux
I added | #if 0 | around the code to fill the thread context, but left the code in because I think we'll evenually want to reuse some of that code. --- xpcom/threads/ThreadStackHelper.cpp | 169 ++--------------------------------- xpcom/threads/ThreadStackHelper.h | 1 - 2 files changed, 6 insertions(+), 164 deletions(-)
diff --git a/xpcom/threads/ThreadStackHelper.cpp b/xpcom/threads/ThreadStackHelper.cpp index 07a8e2d..a937e7f 100644 --- a/xpcom/threads/ThreadStackHelper.cpp +++ b/xpcom/threads/ThreadStackHelper.cpp @@ -22,22 +22,6 @@ #include "mozilla/UniquePtr.h" #include "mozilla/MemoryChecking.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 @@ -286,67 +270,12 @@ ThreadStackHelper::GetStack(Stack& aStack) }
#ifdef MOZ_THREADSTACKHELPER_NATIVE -class ThreadStackHelper::CodeModulesProvider - : public google_breakpad::CodeModules +class ThreadStackHelper::ThreadContext final { -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"); - } + // TODO: provide per-platform definition of Context. + typedef struct {} Context;
- 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 - : 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 // Limit copied stack to 4kB static const size_t kMaxStackSize = 0x1000; // Limit unwound stack to 32 frames @@ -369,38 +298,6 @@ public: , 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
@@ -417,63 +314,7 @@ ThreadStackHelper::GetNativeStack(Stack& aStack) 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 = PR_snprintf(buffer, sizeof(buffer), "%s:%s", - module_name, frame.function_name.c_str()); - } else { - len = PR_snprintf(buffer, sizeof(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 }
@@ -701,6 +542,7 @@ ThreadStackHelper::FillThreadContext(void* aContext) 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) @@ -858,6 +700,7 @@ ThreadStackHelper::FillThreadContext(void* aContext) mContextToFill->mStackBase = uintptr_t(sp); mContextToFill->mStackSize = stackSize; mContextToFill->mValid = true; +#endif #endif // MOZ_THREADSTACKHELPER_NATIVE }
diff --git a/xpcom/threads/ThreadStackHelper.h b/xpcom/threads/ThreadStackHelper.h index b334f2f..9c40ad5 100644 --- a/xpcom/threads/ThreadStackHelper.h +++ b/xpcom/threads/ThreadStackHelper.h @@ -66,7 +66,6 @@ private: #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;
tor-commits@lists.torproject.org