diff options
Diffstat (limited to 'src')
16 files changed, 192 insertions, 92 deletions
diff --git a/src/common/windows/pdb_source_line_writer.h b/src/common/windows/pdb_source_line_writer.h index a2818263..58c8f5e0 100644 --- a/src/common/windows/pdb_source_line_writer.h +++ b/src/common/windows/pdb_source_line_writer.h @@ -28,7 +28,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // PDBSourceLineWriter uses a pdb file produced by Visual C++ to output -// a line/address map for use with SourceLineResolver. +// a line/address map for use with BasicSourceLineResolver. #ifndef _PDB_SOURCE_LINE_WRITER_H__ #define _PDB_SOURCE_LINE_WRITER_H__ diff --git a/src/google_airbag/processor/basic_source_line_resolver.h b/src/google_airbag/processor/basic_source_line_resolver.h new file mode 100644 index 00000000..c688191a --- /dev/null +++ b/src/google_airbag/processor/basic_source_line_resolver.h @@ -0,0 +1,84 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// BasicSourceLineResolver implements SourceLineResolverInterface, using +// address map files produced by a compatible writer, e.g. PDBSourceLineWriter. + +#ifndef GOOGLE_AIRBAG_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__ +#define GOOGLE_AIRBAG_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__ + +#include <ext/hash_map> + +#include "google_airbag/processor/source_line_resolver_interface.h" + +namespace google_airbag { + +using std::string; +using __gnu_cxx::hash_map; + +class BasicSourceLineResolver : public SourceLineResolverInterface { + public: + BasicSourceLineResolver(); + virtual ~BasicSourceLineResolver(); + + // SourceLineResolverInterface methods, see source_line_resolver_interface.h + // for more details. + + // Adds a module to this resolver, returning true on success. + // The given map_file is read into memory, and its symbols will be + // retained until the BasicSourceLineResolver is destroyed. + virtual bool LoadModule(const string &module_name, const string &map_file); + + virtual bool HasModule(const string &module_name) const; + + virtual StackFrameInfo* FillSourceLineInfo(StackFrame *frame) const; + + private: + template<class T> class MemAddrMap; + struct Line; + struct Function; + struct PublicSymbol; + struct File; + struct HashString { + size_t operator()(const string &s) const; + }; + class Module; + + // All of the modules we've loaded + typedef hash_map<string, Module*, HashString> ModuleMap; + ModuleMap *modules_; + + // Disallow unwanted copy ctor and assignment operator + BasicSourceLineResolver(const BasicSourceLineResolver&); + void operator=(const BasicSourceLineResolver&); +}; + +} // namespace google_airbag + +#endif // GOOGLE_AIRBAG_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__ diff --git a/src/google_airbag/processor/minidump_processor.h b/src/google_airbag/processor/minidump_processor.h index 604eae45..a50d8a79 100644 --- a/src/google_airbag/processor/minidump_processor.h +++ b/src/google_airbag/processor/minidump_processor.h @@ -38,6 +38,7 @@ using std::string; class Minidump; class ProcessState; +class SourceLineResolverInterface; class SymbolSupplier; class MinidumpProcessor { @@ -51,7 +52,8 @@ class MinidumpProcessor { // Initializes this MinidumpProcessor. supplier should be an // implementation of the SymbolSupplier abstract base class. - explicit MinidumpProcessor(SymbolSupplier *supplier); + MinidumpProcessor(SymbolSupplier *supplier, + SourceLineResolverInterface *resolver); ~MinidumpProcessor(); // Processes the minidump file and fills process_state with the result. @@ -84,6 +86,7 @@ class MinidumpProcessor { private: SymbolSupplier *supplier_; + SourceLineResolverInterface *resolver_; }; } // namespace google_airbag diff --git a/src/processor/source_line_resolver.h b/src/google_airbag/processor/source_line_resolver_interface.h index 3e992607..2afd4d8f 100644 --- a/src/processor/source_line_resolver.h +++ b/src/google_airbag/processor/source_line_resolver_interface.h @@ -27,31 +27,26 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// SourceLineResolver returns function/file/line info for a memory address. -// It uses address map files produced by a compatible writer, e.g. -// PDBSourceLineWriter. +// Abstract interface to return function/file/line info for a memory address. -#ifndef PROCESSOR_SOURCE_LINE_RESOLVER_H__ -#define PROCESSOR_SOURCE_LINE_RESOLVER_H__ +#ifndef GOOGLE_AIRBAG_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H__ +#define GOOGLE_AIRBAG_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H__ #include <string> -#include <ext/hash_map> #include "google_airbag/common/airbag_types.h" namespace google_airbag { using std::string; -using __gnu_cxx::hash_map; struct StackFrame; struct StackFrameInfo; -class SourceLineResolver { +class SourceLineResolverInterface { public: typedef u_int64_t MemAddr; - SourceLineResolver(); - ~SourceLineResolver(); + virtual ~SourceLineResolverInterface() {} // Adds a module to this resolver, returning true on success. // @@ -59,10 +54,11 @@ class SourceLineResolver { // filename of the module, optionally with version identifiers. // // map_file should contain line/address mappings for this module. - bool LoadModule(const string &module_name, const string &map_file); + virtual bool LoadModule(const string &module_name, + const string &map_file) = 0; // Returns true if a module with the given name has been loaded. - bool HasModule(const string &module_name) const; + virtual bool HasModule(const string &module_name) const = 0; // Fills in the function_base, function_name, source_file_name, // and source_line fields of the StackFrame. The instruction and @@ -71,28 +67,13 @@ class SourceLineResolver { // available, returns NULL. A NULL return value does not indicate an // error. The caller takes ownership of any returned StackFrameInfo // object. - StackFrameInfo* FillSourceLineInfo(StackFrame *frame) const; + virtual StackFrameInfo* FillSourceLineInfo(StackFrame *frame) const = 0; - private: - template<class T> class MemAddrMap; - struct Line; - struct Function; - struct PublicSymbol; - struct File; - struct HashString { - size_t operator()(const string &s) const; - }; - class Module; - - // All of the modules we've loaded - typedef hash_map<string, Module*, HashString> ModuleMap; - ModuleMap *modules_; - - // Disallow unwanted copy ctor and assignment operator - SourceLineResolver(const SourceLineResolver&); - void operator=(const SourceLineResolver&); + protected: + // SourceLineResolverInterface cannot be instantiated except by subclasses + SourceLineResolverInterface() {} }; } // namespace google_airbag -#endif // PROCESSOR_SOURCE_LINE_RESOLVER_H__ +#endif // GOOGLE_AIRBAG_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H__ diff --git a/src/google_airbag/processor/stackwalker.h b/src/google_airbag/processor/stackwalker.h index 70da125e..381b9e29 100644 --- a/src/google_airbag/processor/stackwalker.h +++ b/src/google_airbag/processor/stackwalker.h @@ -50,6 +50,7 @@ class CodeModules; template<typename T> class linked_ptr; class MemoryRegion; class MinidumpContext; +class SourceLineResolverInterface; struct StackFrame; struct StackFrameInfo; class SymbolSupplier; @@ -73,7 +74,8 @@ class Stackwalker { static Stackwalker* StackwalkerForCPU(MinidumpContext *context, MemoryRegion *memory, const CodeModules *modules, - SymbolSupplier *supplier); + SymbolSupplier *supplier, + SourceLineResolverInterface *resolver); protected: // memory identifies a MemoryRegion that provides the stack memory @@ -81,10 +83,13 @@ class Stackwalker { // object that is used to look up which code module each stack frame is // associated with. supplier is an optional caller-supplied SymbolSupplier // implementation. If supplier is NULL, source line info will not be - // resolved. + // resolved. resolver is an instance of SourceLineResolverInterface + // (see source_line_resolver_interface.h and basic_source_line_resolver.h). + // If resolver is NULL, source line info will not be resolved. Stackwalker(MemoryRegion *memory, const CodeModules *modules, - SymbolSupplier *supplier); + SymbolSupplier *supplier, + SourceLineResolverInterface *resolver); // The stack memory to walk. Subclasses will require this region to // get information from the stack. @@ -115,6 +120,9 @@ class Stackwalker { // The optional SymbolSupplier for resolving source line info. SymbolSupplier *supplier_; + + // The SourceLineResolver implementation + SourceLineResolverInterface *resolver_; }; diff --git a/src/processor/source_line_resolver.cc b/src/processor/basic_source_line_resolver.cc index 1ebc1bf4..a170be6e 100644 --- a/src/processor/source_line_resolver.cc +++ b/src/processor/basic_source_line_resolver.cc @@ -38,7 +38,7 @@ #include "processor/contained_range_map-inl.h" #include "processor/range_map-inl.h" -#include "processor/source_line_resolver.h" +#include "google_airbag/processor/basic_source_line_resolver.h" #include "google_airbag/processor/code_module.h" #include "google_airbag/processor/stack_frame.h" #include "processor/linked_ptr.h" @@ -52,7 +52,7 @@ using __gnu_cxx::hash; namespace google_airbag { -struct SourceLineResolver::Line { +struct BasicSourceLineResolver::Line { Line(MemAddr addr, MemAddr code_size, int file_id, int source_line) : address(addr) , size(code_size) @@ -65,7 +65,7 @@ struct SourceLineResolver::Line { int line; }; -struct SourceLineResolver::Function { +struct BasicSourceLineResolver::Function { Function(const string &function_name, MemAddr function_address, MemAddr code_size, @@ -83,7 +83,7 @@ struct SourceLineResolver::Function { RangeMap< MemAddr, linked_ptr<Line> > lines; }; -struct SourceLineResolver::PublicSymbol { +struct BasicSourceLineResolver::PublicSymbol { PublicSymbol(const string& set_name, MemAddr set_address, int set_parameter_size) @@ -100,7 +100,7 @@ struct SourceLineResolver::PublicSymbol { int parameter_size; }; -class SourceLineResolver::Module { +class BasicSourceLineResolver::Module { public: Module(const string &name) : name_(name) { } @@ -115,7 +115,7 @@ class SourceLineResolver::Module { StackFrameInfo* LookupAddress(StackFrame *frame) const; private: - friend class SourceLineResolver; + friend class BasicSourceLineResolver; typedef hash_map<int, string> FileMap; // The types for stack_info_. This is equivalent to MS DIA's @@ -173,10 +173,10 @@ class SourceLineResolver::Module { stack_info_[STACK_INFO_LAST]; }; -SourceLineResolver::SourceLineResolver() : modules_(new ModuleMap) { +BasicSourceLineResolver::BasicSourceLineResolver() : modules_(new ModuleMap) { } -SourceLineResolver::~SourceLineResolver() { +BasicSourceLineResolver::~BasicSourceLineResolver() { ModuleMap::iterator it; for (it = modules_->begin(); it != modules_->end(); ++it) { delete it->second; @@ -184,8 +184,8 @@ SourceLineResolver::~SourceLineResolver() { delete modules_; } -bool SourceLineResolver::LoadModule(const string &module_name, - const string &map_file) { +bool BasicSourceLineResolver::LoadModule(const string &module_name, + const string &map_file) { // Make sure we don't already have a module with the given name. if (modules_->find(module_name) != modules_->end()) { return false; @@ -201,11 +201,11 @@ bool SourceLineResolver::LoadModule(const string &module_name, return true; } -bool SourceLineResolver::HasModule(const string &module_name) const { +bool BasicSourceLineResolver::HasModule(const string &module_name) const { return modules_->find(module_name) != modules_->end(); } -StackFrameInfo* SourceLineResolver::FillSourceLineInfo( +StackFrameInfo* BasicSourceLineResolver::FillSourceLineInfo( StackFrame *frame) const { if (frame->module) { ModuleMap::const_iterator it = modules_->find(frame->module->code_file()); @@ -216,7 +216,7 @@ StackFrameInfo* SourceLineResolver::FillSourceLineInfo( return NULL; } -bool SourceLineResolver::Module::LoadMap(const string &map_file) { +bool BasicSourceLineResolver::Module::LoadMap(const string &map_file) { FILE *f = fopen(map_file.c_str(), "r"); if (!f) { return false; @@ -252,8 +252,8 @@ bool SourceLineResolver::Module::LoadMap(const string &map_file) { return false; } } else if (strncmp(buffer, "MODULE ", 7) == 0) { - // Ignore these. They're not of any use to SourceLineResolver, which - // is fed modules by a SymbolSupplier. These lines are present to + // Ignore these. They're not of any use to BasicSourceLineResolver, + // which is fed modules by a SymbolSupplier. These lines are present to // aid other tools in properly placing symbol files so that they can // be accessed by a SymbolSupplier. // @@ -275,8 +275,8 @@ bool SourceLineResolver::Module::LoadMap(const string &map_file) { return true; } -StackFrameInfo* SourceLineResolver::Module::LookupAddress(StackFrame *frame) - const { +StackFrameInfo* BasicSourceLineResolver::Module::LookupAddress( + StackFrame *frame) const { MemAddr address = frame->instruction - frame->module->base_address(); linked_ptr<StackFrameInfo> retrieved_info; @@ -360,8 +360,8 @@ StackFrameInfo* SourceLineResolver::Module::LookupAddress(StackFrame *frame) } // static -bool SourceLineResolver::Module::Tokenize(char *line, int max_tokens, - vector<char*> *tokens) { +bool BasicSourceLineResolver::Module::Tokenize(char *line, int max_tokens, + vector<char*> *tokens) { tokens->clear(); tokens->reserve(max_tokens); @@ -387,7 +387,7 @@ bool SourceLineResolver::Module::Tokenize(char *line, int max_tokens, return tokens->size() == static_cast<unsigned int>(max_tokens); } -void SourceLineResolver::Module::ParseFile(char *file_line) { +void BasicSourceLineResolver::Module::ParseFile(char *file_line) { // FILE <id> <filename> file_line += 5; // skip prefix @@ -407,8 +407,8 @@ void SourceLineResolver::Module::ParseFile(char *file_line) { } } -SourceLineResolver::Function* SourceLineResolver::Module::ParseFunction( - char *function_line) { +BasicSourceLineResolver::Function* +BasicSourceLineResolver::Module::ParseFunction(char *function_line) { // FUNC <address> <size> <stack_param_size> <name> function_line += 5; // skip prefix @@ -425,7 +425,7 @@ SourceLineResolver::Function* SourceLineResolver::Module::ParseFunction( return new Function(name, address, size, stack_param_size); } -SourceLineResolver::Line* SourceLineResolver::Module::ParseLine( +BasicSourceLineResolver::Line* BasicSourceLineResolver::Module::ParseLine( char *line_line) { // <address> <line number> <source file id> vector<char*> tokens; @@ -444,7 +444,7 @@ SourceLineResolver::Line* SourceLineResolver::Module::ParseLine( return new Line(address, size, source_file, line_number); } -bool SourceLineResolver::Module::ParsePublicSymbol(char *public_line) { +bool BasicSourceLineResolver::Module::ParsePublicSymbol(char *public_line) { // PUBLIC <address> <stack_param_size> <name> // Skip "PUBLIC " prefix. @@ -474,7 +474,7 @@ bool SourceLineResolver::Module::ParsePublicSymbol(char *public_line) { return public_symbols_.Store(address, symbol); } -bool SourceLineResolver::Module::ParseStackInfo(char *stack_info_line) { +bool BasicSourceLineResolver::Module::ParseStackInfo(char *stack_info_line) { // STACK WIN <type> <rva> <code_size> <prolog_size> <epliog_size> // <parameter_size> <saved_register_size> <local_size> <max_stack_size> // <has_program_string> <program_string_OR_allocates_base_pointer> @@ -554,7 +554,7 @@ bool SourceLineResolver::Module::ParseStackInfo(char *stack_info_line) { return true; } -size_t SourceLineResolver::HashString::operator()(const string &s) const { +size_t BasicSourceLineResolver::HashString::operator()(const string &s) const { return hash<const char*>()(s.c_str()); } diff --git a/src/processor/source_line_resolver_unittest.cc b/src/processor/basic_source_line_resolver_unittest.cc index 38de9e2c..8ad7183f 100644 --- a/src/processor/source_line_resolver_unittest.cc +++ b/src/processor/basic_source_line_resolver_unittest.cc @@ -29,7 +29,7 @@ #include <cstdio> #include <string> -#include "processor/source_line_resolver.h" +#include "google_airbag/processor/basic_source_line_resolver.h" #include "google_airbag/processor/code_module.h" #include "google_airbag/processor/stack_frame.h" #include "processor/linked_ptr.h" @@ -49,10 +49,10 @@ namespace { using std::string; +using google_airbag::BasicSourceLineResolver; using google_airbag::CodeModule; using google_airbag::linked_ptr; using google_airbag::scoped_ptr; -using google_airbag::SourceLineResolver; using google_airbag::StackFrame; using google_airbag::StackFrameInfo; @@ -94,7 +94,7 @@ static bool RunTests() { string testdata_dir = string(getenv("srcdir") ? getenv("srcdir") : ".") + "/src/processor/testdata"; - SourceLineResolver resolver; + BasicSourceLineResolver resolver; ASSERT_TRUE(resolver.LoadModule("module1", testdata_dir + "/module1.out")); ASSERT_TRUE(resolver.HasModule("module1")); ASSERT_TRUE(resolver.LoadModule("module2", testdata_dir + "/module2.out")); diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc index ab027e8a..dd4c7156 100644 --- a/src/processor/minidump_processor.cc +++ b/src/processor/minidump_processor.cc @@ -38,8 +38,9 @@ namespace google_airbag { -MinidumpProcessor::MinidumpProcessor(SymbolSupplier *supplier) - : supplier_(supplier) { +MinidumpProcessor::MinidumpProcessor(SymbolSupplier *supplier, + SourceLineResolverInterface *resolver) + : supplier_(supplier), resolver_(resolver) { } MinidumpProcessor::~MinidumpProcessor() { @@ -164,7 +165,8 @@ MinidumpProcessor::ProcessResult MinidumpProcessor::Process( Stackwalker::StackwalkerForCPU(context, thread_memory, process_state->modules_, - supplier_)); + supplier_, + resolver_)); if (!stackwalker.get()) { return PROCESS_ERROR; } diff --git a/src/processor/minidump_processor_unittest.cc b/src/processor/minidump_processor_unittest.cc index 766c2a30..69a29965 100644 --- a/src/processor/minidump_processor_unittest.cc +++ b/src/processor/minidump_processor_unittest.cc @@ -31,6 +31,7 @@ // corresponding symbol file, and checks the stack frames for correctness. #include <string> +#include "google_airbag/processor/basic_source_line_resolver.h" #include "google_airbag/processor/call_stack.h" #include "google_airbag/processor/code_module.h" #include "google_airbag/processor/code_modules.h" @@ -43,6 +44,7 @@ namespace { using std::string; +using google_airbag::BasicSourceLineResolver; using google_airbag::CallStack; using google_airbag::CodeModule; using google_airbag::MinidumpProcessor; @@ -93,7 +95,8 @@ SymbolSupplier::SymbolResult TestSymbolSupplier::GetSymbolFile( static bool RunTests() { TestSymbolSupplier supplier; - MinidumpProcessor processor(&supplier); + BasicSourceLineResolver resolver; + MinidumpProcessor processor(&supplier, &resolver); string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + "/src/processor/testdata/minidump2.dmp"; diff --git a/src/processor/minidump_stackwalk.cc b/src/processor/minidump_stackwalk.cc index 3c55933d..2bd32d7a 100644 --- a/src/processor/minidump_stackwalk.cc +++ b/src/processor/minidump_stackwalk.cc @@ -36,6 +36,7 @@ #include <cstdlib> #include <string> +#include "google_airbag/processor/basic_source_line_resolver.h" #include "google_airbag/processor/call_stack.h" #include "google_airbag/processor/code_module.h" #include "google_airbag/processor/code_modules.h" @@ -50,6 +51,7 @@ namespace { using std::string; +using google_airbag::BasicSourceLineResolver; using google_airbag::CallStack; using google_airbag::CodeModule; using google_airbag::CodeModules; @@ -192,7 +194,8 @@ static bool PrintMinidumpProcess(const string &minidump_file, symbol_supplier.reset(new SimpleSymbolSupplier(symbol_path)); } - MinidumpProcessor minidump_processor(symbol_supplier.get()); + BasicSourceLineResolver resolver; + MinidumpProcessor minidump_processor(symbol_supplier.get(), &resolver); // Process the minidump. ProcessState process_state; diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc index edbe428a..e6a26bb9 100644 --- a/src/processor/stackwalker.cc +++ b/src/processor/stackwalker.cc @@ -41,11 +41,11 @@ #include "google_airbag/processor/code_module.h" #include "google_airbag/processor/code_modules.h" #include "google_airbag/processor/minidump.h" +#include "google_airbag/processor/source_line_resolver_interface.h" #include "google_airbag/processor/stack_frame.h" #include "google_airbag/processor/symbol_supplier.h" #include "processor/linked_ptr.h" #include "processor/scoped_ptr.h" -#include "processor/source_line_resolver.h" #include "processor/stack_frame_info.h" #include "processor/stackwalker_ppc.h" #include "processor/stackwalker_x86.h" @@ -54,14 +54,17 @@ namespace google_airbag { Stackwalker::Stackwalker(MemoryRegion *memory, const CodeModules *modules, - SymbolSupplier *supplier) - : memory_(memory), modules_(modules), supplier_(supplier) { + SymbolSupplier *supplier, + SourceLineResolverInterface *resolver) + : memory_(memory), + modules_(modules), + supplier_(supplier), + resolver_(resolver) { } bool Stackwalker::Walk(CallStack *stack) { assert(stack); - SourceLineResolver resolver; stack->Clear(); // stack_frame_info parallels the CallStack. The vector is passed to the @@ -88,14 +91,16 @@ bool Stackwalker::Walk(CallStack *stack) { modules_->GetModuleForAddress(frame->instruction); if (module) { frame->module = module; - if (!resolver.HasModule(frame->module->code_file()) && supplier_) { + if (resolver_ && + !resolver_->HasModule(frame->module->code_file()) && + supplier_) { string symbol_file; SymbolSupplier::SymbolResult symbol_result = supplier_->GetSymbolFile(module, &symbol_file); switch (symbol_result) { case SymbolSupplier::FOUND: - resolver.LoadModule(frame->module->code_file(), symbol_file); + resolver_->LoadModule(frame->module->code_file(), symbol_file); break; case SymbolSupplier::NOT_FOUND: break; // nothing to do @@ -103,7 +108,7 @@ bool Stackwalker::Walk(CallStack *stack) { return false; } } - frame_info.reset(resolver.FillSourceLineInfo(frame.get())); + frame_info.reset(resolver_->FillSourceLineInfo(frame.get())); } } @@ -124,22 +129,26 @@ bool Stackwalker::Walk(CallStack *stack) { // static -Stackwalker* Stackwalker::StackwalkerForCPU(MinidumpContext *context, - MemoryRegion *memory, - const CodeModules *modules, - SymbolSupplier *supplier) { +Stackwalker* Stackwalker::StackwalkerForCPU( + MinidumpContext *context, + MemoryRegion *memory, + const CodeModules *modules, + SymbolSupplier *supplier, + SourceLineResolverInterface *resolver) { Stackwalker *cpu_stackwalker = NULL; u_int32_t cpu = context->GetContextCPU(); switch (cpu) { case MD_CONTEXT_X86: cpu_stackwalker = new StackwalkerX86(context->GetContextX86(), - memory, modules, supplier); + memory, modules, supplier, + resolver); break; case MD_CONTEXT_PPC: cpu_stackwalker = new StackwalkerPPC(context->GetContextPPC(), - memory, modules, supplier); + memory, modules, supplier, + resolver); break; } diff --git a/src/processor/stackwalker_ppc.cc b/src/processor/stackwalker_ppc.cc index 49b62f8c..ff5243c6 100644 --- a/src/processor/stackwalker_ppc.cc +++ b/src/processor/stackwalker_ppc.cc @@ -45,8 +45,9 @@ namespace google_airbag { StackwalkerPPC::StackwalkerPPC(const MDRawContextPPC *context, MemoryRegion *memory, const CodeModules *modules, - SymbolSupplier *supplier) - : Stackwalker(memory, modules, supplier), + SymbolSupplier *supplier, + SourceLineResolverInterface *resolver) + : Stackwalker(memory, modules, supplier, resolver), context_(context) { if (memory_->GetBase() + memory_->GetSize() - 1 > 0xffffffff) { // This implementation only covers 32-bit ppc CPUs. The limits of the diff --git a/src/processor/stackwalker_ppc.h b/src/processor/stackwalker_ppc.h index bccc9dc2..9901f673 100644 --- a/src/processor/stackwalker_ppc.h +++ b/src/processor/stackwalker_ppc.h @@ -56,7 +56,8 @@ class StackwalkerPPC : public Stackwalker { StackwalkerPPC(const MDRawContextPPC *context, MemoryRegion *memory, const CodeModules *modules, - SymbolSupplier *supplier); + SymbolSupplier *supplier, + SourceLineResolverInterface *resolver); private: // Implementation of Stackwalker, using ppc context (stack pointer in %r1, diff --git a/src/processor/stackwalker_selftest.cc b/src/processor/stackwalker_selftest.cc index 877a8f3d..e645dd98 100644 --- a/src/processor/stackwalker_selftest.cc +++ b/src/processor/stackwalker_selftest.cc @@ -217,6 +217,7 @@ static u_int32_t GetPC() { static unsigned int CountCallerFrames() __attribute__((noinline)); static unsigned int CountCallerFrames() { SelfMemoryRegion memory; + BasicSourceLineResolver resolver; #if defined(__i386__) MDRawContextX86 context = MDRawContextX86(); @@ -224,13 +225,15 @@ static unsigned int CountCallerFrames() { context.ebp = GetEBP(); context.esp = GetESP(); - StackwalkerX86 stackwalker = StackwalkerX86(&context, &memory, NULL, NULL); + StackwalkerX86 stackwalker = StackwalkerX86(&context, &memory, NULL, NULL, + &resolver); #elif defined(__ppc__) MDRawContextPPC context = MDRawContextPPC(); context.srr0 = GetPC(); context.gpr[1] = GetSP(); - StackwalkerPPC stackwalker = StackwalkerPPC(&context, &memory, NULL, NULL); + StackwalkerPPC stackwalker = StackwalkerPPC(&context, &memory, NULL, NULL, + &resolver); #endif // __i386__ || __ppc__ scoped_ptr<CallStack> stack(stackwalker.Walk()); diff --git a/src/processor/stackwalker_x86.cc b/src/processor/stackwalker_x86.cc index 1e3390f5..0ee2fbd2 100644 --- a/src/processor/stackwalker_x86.cc +++ b/src/processor/stackwalker_x86.cc @@ -49,8 +49,9 @@ namespace google_airbag { StackwalkerX86::StackwalkerX86(const MDRawContextX86 *context, MemoryRegion *memory, const CodeModules *modules, - SymbolSupplier *supplier) - : Stackwalker(memory, modules, supplier), + SymbolSupplier *supplier, + SourceLineResolverInterface *resolver) + : Stackwalker(memory, modules, supplier, resolver), context_(context) { if (memory_->GetBase() + memory_->GetSize() - 1 > 0xffffffff) { // The x86 is a 32-bit CPU, the limits of the supplied stack are invalid. diff --git a/src/processor/stackwalker_x86.h b/src/processor/stackwalker_x86.h index fe2a7808..f53fc5f7 100644 --- a/src/processor/stackwalker_x86.h +++ b/src/processor/stackwalker_x86.h @@ -57,7 +57,8 @@ class StackwalkerX86 : public Stackwalker { StackwalkerX86(const MDRawContextX86 *context, MemoryRegion *memory, const CodeModules *modules, - SymbolSupplier *supplier); + SymbolSupplier *supplier, + SourceLineResolverInterface *resolver); private: // Implementation of Stackwalker, using x86 context (%ebp, %esp, %eip) and |