mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-10 17:24:29 +00:00
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.
This commit is contained in:
parent
b4389f1282
commit
5d85f6dea6
@ -22,22 +22,6 @@
|
||||
#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
|
||||
@ -287,67 +271,12 @@ ThreadStackHelper::GetStack(Stack& aStack)
|
||||
}
|
||||
|
||||
#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
|
||||
@ -370,38 +299,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
|
||||
|
||||
@ -418,63 +315,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 = 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
|
||||
}
|
||||
|
||||
@ -707,6 +548,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)
|
||||
@ -864,6 +706,7 @@ ThreadStackHelper::FillThreadContext(void* aContext)
|
||||
mContextToFill->mStackBase = uintptr_t(sp);
|
||||
mContextToFill->mStackSize = stackSize;
|
||||
mContextToFill->mValid = true;
|
||||
#endif
|
||||
#endif // MOZ_THREADSTACKHELPER_NATIVE
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user