TEST_F(ElfCacheTest, SignalSafeElfCache) { SignalSafeElfCache cache(100); Symbolizer symbolizer(&cache); for (size_t i = 0; i < 2; ++i) { runElfCacheTest(symbolizer); } }
TEST_F(ElfCacheTest, TinyElfCache) { ElfCache cache(1); Symbolizer symbolizer(&cache); // Run twice, in case the wrong stuff gets evicted? for (size_t i = 0; i < 2; ++i) { runElfCacheTest(symbolizer); } }
void printExceptionInfo( std::ostream& out, const ExceptionInfo& info, int options) { out << "Exception type: "; if (info.type) { out << folly::demangle(*info.type); } else { out << "(unknown type)"; } out << " (" << info.frames.size() << (info.frames.size() == 1 ? " frame" : " frames") << ")\n"; try { size_t frameCount = info.frames.size(); // Skip our own internal frames static constexpr size_t kInternalFramesNumber = 3; if (frameCount > kInternalFramesNumber) { auto addresses = info.frames.data() + kInternalFramesNumber; frameCount -= kInternalFramesNumber; std::vector<SymbolizedFrame> frames; frames.resize(frameCount); Symbolizer symbolizer( (options & SymbolizePrinter::NO_FILE_AND_LINE) ? Dwarf::LocationInfoMode::DISABLED : Symbolizer::kDefaultLocationInfoMode); symbolizer.symbolize(addresses, frames.data(), frameCount); OStreamSymbolizePrinter osp(out, options); osp.println(addresses, frames.data(), frameCount); } } catch (const std::exception& e) { out << "\n !! caught " << folly::exceptionStr(e) << "\n"; } catch (...) { out << "\n !!! caught unexpected exception\n"; } }
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 = 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); } } #endif // MOZ_THREADSTACKHELPER_NATIVE }
inline symbolizer init_symbolizer() { return symbolizer(); }