From bab770045bb2cdedce4046400544904fc40c6703 Mon Sep 17 00:00:00 2001 From: "SiyangXie@gmail.com" Date: Wed, 10 Oct 2012 21:41:52 +0000 Subject: Refactor the logic of resolving source line info into helper class. http://breakpad.appspot.com/459002/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1068 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/processor/stackwalker.cc | 125 ++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 86 deletions(-) (limited to 'src/processor/stackwalker.cc') diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc index 2bd333ac..762c47f5 100644 --- a/src/processor/stackwalker.cc +++ b/src/processor/stackwalker.cc @@ -41,9 +41,8 @@ #include "google_breakpad/processor/code_module.h" #include "google_breakpad/processor/code_modules.h" #include "google_breakpad/processor/minidump.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" #include "google_breakpad/processor/stack_frame.h" -#include "google_breakpad/processor/symbol_supplier.h" +#include "google_breakpad/processor/stack_frame_symbolizer.h" #include "google_breakpad/processor/system_info.h" #include "processor/linked_ptr.h" #include "processor/logging.h" @@ -58,20 +57,19 @@ namespace google_breakpad { u_int32_t Stackwalker::max_frames_ = 1024; -Stackwalker::Stackwalker(const SystemInfo *system_info, - MemoryRegion *memory, - const CodeModules *modules, - SymbolSupplier *supplier, - SourceLineResolverInterface *resolver) +Stackwalker::Stackwalker(const SystemInfo* system_info, + MemoryRegion* memory, + const CodeModules* modules, + StackFrameSymbolizer* frame_symbolizer) : system_info_(system_info), memory_(memory), modules_(modules), - resolver_(resolver), - supplier_(supplier) { + frame_symbolizer_(frame_symbolizer) { + assert(frame_symbolizer_); } -bool Stackwalker::Walk(CallStack *stack) { +bool Stackwalker::Walk(CallStack* stack) { BPLOG_IF(ERROR, !stack) << "Stackwalker::Walk requires |stack|"; assert(stack); stack->Clear(); @@ -88,42 +86,12 @@ bool Stackwalker::Walk(CallStack *stack) { // context frame (above) or a caller frame (below). // Resolve the module information, if a module map was provided. - if (modules_) { - const CodeModule *module = - modules_->GetModuleForAddress(frame->instruction); - if (module) { - frame->module = module; - if (resolver_ && - !resolver_->HasModule(frame->module) && - no_symbol_modules_.find( - module->code_file()) == no_symbol_modules_.end() && - supplier_) { - string symbol_file; - char *symbol_data = NULL; - SymbolSupplier::SymbolResult symbol_result = - supplier_->GetCStringSymbolData(module, - system_info_, - &symbol_file, - &symbol_data); - - switch (symbol_result) { - case SymbolSupplier::FOUND: - resolver_->LoadModuleUsingMemoryBuffer(frame->module, - symbol_data); - break; - case SymbolSupplier::NOT_FOUND: - no_symbol_modules_.insert(module->code_file()); - break; // nothing to do - case SymbolSupplier::INTERRUPT: - return false; - } - // Inform symbol supplier to free the unused data memory buffer. - if (resolver_->ShouldDeleteMemoryBufferAfterLoadModule()) - supplier_->FreeSymbolData(module); - } - if (resolver_) - resolver_->FillSourceLineInfo(frame.get()); - } + StackFrameSymbolizer::SymbolizerResult symbolizer_result = + frame_symbolizer_->FillSourceLineInfo(modules_, system_info_, + frame.get()); + if (symbolizer_result == StackFrameSymbolizer::INTERRUPT) { + BPLOG(INFO) << "Stack walk is interrupted."; + return false; } // Add the frame to the call stack. Relinquish the ownership claim @@ -144,47 +112,42 @@ bool Stackwalker::Walk(CallStack *stack) { // static Stackwalker* Stackwalker::StackwalkerForCPU( - const SystemInfo *system_info, - MinidumpContext *context, - MemoryRegion *memory, - const CodeModules *modules, - SymbolSupplier *supplier, - SourceLineResolverInterface *resolver) { + const SystemInfo* system_info, + MinidumpContext* context, + MemoryRegion* memory, + const CodeModules* modules, + StackFrameSymbolizer* frame_symbolizer) { if (!context) { BPLOG(ERROR) << "Can't choose a stackwalker implementation without context"; return NULL; } - Stackwalker *cpu_stackwalker = NULL; + Stackwalker* cpu_stackwalker = NULL; u_int32_t cpu = context->GetContextCPU(); switch (cpu) { case MD_CONTEXT_X86: cpu_stackwalker = new StackwalkerX86(system_info, context->GetContextX86(), - memory, modules, supplier, - resolver); + memory, modules, frame_symbolizer); break; case MD_CONTEXT_PPC: cpu_stackwalker = new StackwalkerPPC(system_info, context->GetContextPPC(), - memory, modules, supplier, - resolver); + memory, modules, frame_symbolizer); break; case MD_CONTEXT_AMD64: cpu_stackwalker = new StackwalkerAMD64(system_info, context->GetContextAMD64(), - memory, modules, supplier, - resolver); + memory, modules, frame_symbolizer); break; case MD_CONTEXT_SPARC: cpu_stackwalker = new StackwalkerSPARC(system_info, context->GetContextSPARC(), - memory, modules, supplier, - resolver); + memory, modules, frame_symbolizer); break; case MD_CONTEXT_ARM: @@ -193,8 +156,8 @@ Stackwalker* Stackwalker::StackwalkerForCPU( fp_register = MD_CONTEXT_ARM_REG_IOS_FP; cpu_stackwalker = new StackwalkerARM(system_info, context->GetContextARM(), - fp_register, memory, modules, - supplier, resolver); + fp_register, memory, modules, + frame_symbolizer); break; } @@ -205,38 +168,28 @@ Stackwalker* Stackwalker::StackwalkerForCPU( } bool Stackwalker::InstructionAddressSeemsValid(u_int64_t address) { - const CodeModule *module = modules_->GetModuleForAddress(address); - if (!module) { + StackFrame frame; + frame.instruction = address; + StackFrameSymbolizer::SymbolizerResult symbolizer_result = + frame_symbolizer_->FillSourceLineInfo(modules_, system_info_, &frame); + + if (!frame.module) { // not inside any loaded module return false; } - if (!resolver_ || !supplier_) { - // we don't have a resolver and or symbol supplier, - // but we're inside a known module + if (!frame_symbolizer_->HasImplementation()) { + // No valid implementation to symbolize stack frame, but the address is + // within a known module. return true; } - if (!resolver_->HasModule(module)) { - string symbol_file; - char *symbol_data = NULL; - SymbolSupplier::SymbolResult symbol_result = - supplier_->GetCStringSymbolData(module, system_info_, - &symbol_file, &symbol_data); - - if (symbol_result != SymbolSupplier::FOUND || - !resolver_->LoadModuleUsingMemoryBuffer(module, - symbol_data)) { - // we don't have symbols, but we're inside a loaded module - return true; - } + if (symbolizer_result != StackFrameSymbolizer::NO_ERROR) { + // Some error occurred during symbolization, but the address is within a + // known module + return true; } - StackFrame frame; - frame.module = module; - frame.instruction = address; - resolver_->FillSourceLineInfo(&frame); - // we have symbols, so return true if inside a function return !frame.function_name.empty(); } -- cgit v1.2.1