aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSiyangXie@gmail.com <SiyangXie@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2012-10-10 21:41:52 +0000
committerSiyangXie@gmail.com <SiyangXie@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2012-10-10 21:41:52 +0000
commitbab770045bb2cdedce4046400544904fc40c6703 (patch)
tree48e0bf03581bbe0d393746a9051d564ae9e29c53 /src
parentMake Linux signal handler more robust. (diff)
downloadbreakpad-bab770045bb2cdedce4046400544904fc40c6703.tar.xz
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
Diffstat (limited to 'src')
-rw-r--r--src/google_breakpad/processor/minidump_processor.h35
-rw-r--r--src/google_breakpad/processor/stack_frame_cpu.h4
-rw-r--r--src/google_breakpad/processor/stackwalker.h69
-rw-r--r--src/processor/minidump_processor.cc28
-rw-r--r--src/processor/stackwalker.cc125
-rw-r--r--src/processor/stackwalker_amd64.cc39
-rw-r--r--src/processor/stackwalker_amd64.h24
-rw-r--r--src/processor/stackwalker_amd64_unittest.cc27
-rw-r--r--src/processor/stackwalker_arm.cc55
-rw-r--r--src/processor/stackwalker_arm.h23
-rw-r--r--src/processor/stackwalker_arm_unittest.cc30
-rw-r--r--src/processor/stackwalker_ppc.cc21
-rw-r--r--src/processor/stackwalker_ppc.h15
-rw-r--r--src/processor/stackwalker_sparc.cc29
-rw-r--r--src/processor/stackwalker_sparc.h15
-rw-r--r--src/processor/stackwalker_x86.cc71
-rw-r--r--src/processor/stackwalker_x86.h30
-rw-r--r--src/processor/stackwalker_x86_unittest.cc43
18 files changed, 337 insertions, 346 deletions
diff --git a/src/google_breakpad/processor/minidump_processor.h b/src/google_breakpad/processor/minidump_processor.h
index 216e9728..5da11cd3 100644
--- a/src/google_breakpad/processor/minidump_processor.h
+++ b/src/google_breakpad/processor/minidump_processor.h
@@ -40,6 +40,7 @@ namespace google_breakpad {
class Minidump;
class ProcessState;
+class StackFrameSymbolizer;
class SourceLineResolverInterface;
class SymbolSupplier;
struct SystemInfo;
@@ -92,37 +93,44 @@ class MinidumpProcessor {
public:
// Initializes this MinidumpProcessor. supplier should be an
// implementation of the SymbolSupplier abstract base class.
- MinidumpProcessor(SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver);
+ MinidumpProcessor(SymbolSupplier* supplier,
+ SourceLineResolverInterface* resolver);
// Initializes the MinidumpProcessor with the option of
// enabling the exploitability framework to analyze dumps
// for probable security relevance.
- MinidumpProcessor(SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver,
+ MinidumpProcessor(SymbolSupplier* supplier,
+ SourceLineResolverInterface* resolver,
+ bool enable_exploitability);
+
+ // Initializes the MinidumpProcessor with source line resolver helper, and
+ // the option of enabling the exploitability framework to analyze dumps
+ // for probable security relevance.
+ // Does not take ownership of resolver_helper, which must NOT be NULL.
+ MinidumpProcessor(StackFrameSymbolizer* stack_frame_symbolizer,
bool enable_exploitability);
~MinidumpProcessor();
// Processes the minidump file and fills process_state with the result.
ProcessResult Process(const string &minidump_file,
- ProcessState *process_state);
+ ProcessState* process_state);
// Processes the minidump structure and fills process_state with the
// result.
- ProcessResult Process(Minidump *minidump,
- ProcessState *process_state);
+ ProcessResult Process(Minidump* minidump,
+ ProcessState* process_state);
// Populates the cpu_* fields of the |info| parameter with textual
// representations of the CPU type that the minidump in |dump| was
// produced on. Returns false if this information is not available in
// the minidump.
- static bool GetCPUInfo(Minidump *dump, SystemInfo *info);
+ static bool GetCPUInfo(Minidump* dump, SystemInfo* info);
// Populates the os_* fields of the |info| parameter with textual
// representations of the operating system that the minidump in |dump|
// was produced on. Returns false if this information is not available in
// the minidump.
- static bool GetOSInfo(Minidump *dump, SystemInfo *info);
+ static bool GetOSInfo(Minidump* dump, SystemInfo* info);
// Returns a textual representation of the reason that a crash occurred,
// if the minidump in dump was produced as a result of a crash. Returns
@@ -132,7 +140,7 @@ class MinidumpProcessor {
// address when the crash was caused by problems such as illegal
// instructions or divisions by zero, or a data address when the crash
// was caused by a memory access violation.
- static string GetCrashReason(Minidump *dump, u_int64_t *address);
+ static string GetCrashReason(Minidump* dump, u_int64_t* address);
// This function returns true if the passed-in error code is
// something unrecoverable(i.e. retry should not happen). For
@@ -152,11 +160,12 @@ class MinidumpProcessor {
// Returns a textual representation of an assertion included
// in the minidump. Returns an empty string if this information
// does not exist or cannot be determined.
- static string GetAssertion(Minidump *dump);
+ static string GetAssertion(Minidump* dump);
private:
- SymbolSupplier *supplier_;
- SourceLineResolverInterface *resolver_;
+ StackFrameSymbolizer* frame_symbolizer_;
+ // Indicate whether resolver_helper_ is owned by this instance.
+ bool own_frame_symbolizer_;
// This flag enables the exploitability scanner which attempts to
// guess how likely it is that the crash represents an exploitable
diff --git a/src/google_breakpad/processor/stack_frame_cpu.h b/src/google_breakpad/processor/stack_frame_cpu.h
index cc6b0149..90328760 100644
--- a/src/google_breakpad/processor/stack_frame_cpu.h
+++ b/src/google_breakpad/processor/stack_frame_cpu.h
@@ -70,7 +70,7 @@ struct StackFrameX86 : public StackFrame {
CONTEXT_VALID_ALL = -1
};
- StackFrameX86()
+ StackFrameX86()
: context(),
context_validity(CONTEXT_VALID_NONE),
windows_frame_info(NULL),
@@ -220,7 +220,7 @@ struct StackFrameARM : public StackFrame {
// Return the ContextValidity flag for register rN.
static ContextValidity RegisterValidFlag(int n) {
return ContextValidity(1 << n);
- }
+ }
// Register state. This is only fully valid for the topmost frame in a
// stack. In other frames, the values of nonvolatile registers may be
diff --git a/src/google_breakpad/processor/stackwalker.h b/src/google_breakpad/processor/stackwalker.h
index 6a0c3e72..2979fef8 100644
--- a/src/google_breakpad/processor/stackwalker.h
+++ b/src/google_breakpad/processor/stackwalker.h
@@ -48,19 +48,16 @@
#include "google_breakpad/common/breakpad_types.h"
#include "google_breakpad/processor/code_modules.h"
#include "google_breakpad/processor/memory_region.h"
+#include "google_breakpad/processor/stack_frame_symbolizer.h"
namespace google_breakpad {
class CallStack;
class MinidumpContext;
-class SourceLineResolverInterface;
-struct StackFrame;
-class SymbolSupplier;
-struct SystemInfo;
+class StackFrameSymbolizer;
using std::set;
-
class Stackwalker {
public:
virtual ~Stackwalker() {}
@@ -69,17 +66,17 @@ class Stackwalker {
// GetCallerFrame. The frames are further processed to fill all available
// data. Returns true if the stackwalk completed, or false if it was
// interrupted by SymbolSupplier::GetSymbolFile().
- bool Walk(CallStack *stack);
+ bool Walk(CallStack* stack);
// Returns a new concrete subclass suitable for the CPU that a stack was
// generated on, according to the CPU type indicated by the context
// argument. If no suitable concrete subclass exists, returns NULL.
- static Stackwalker* StackwalkerForCPU(const SystemInfo *system_info,
- MinidumpContext *context,
- MemoryRegion *memory,
- const CodeModules *modules,
- SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver);
+ static Stackwalker* StackwalkerForCPU(
+ const SystemInfo* system_info,
+ MinidumpContext* context,
+ MemoryRegion* memory,
+ const CodeModules* modules,
+ StackFrameSymbolizer* resolver_helper);
static void set_max_frames(u_int32_t max_frames) { max_frames_ = max_frames; }
static u_int32_t max_frames() { return max_frames_; }
@@ -89,16 +86,15 @@ class Stackwalker {
// memory identifies a MemoryRegion that provides the stack memory
// for the stack to walk. modules, if non-NULL, is a CodeModules
// 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. 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(const SystemInfo *system_info,
- MemoryRegion *memory,
- const CodeModules *modules,
- SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver);
+ // associated with. frame_symbolizer is a StackFrameSymbolizer object that
+ // encapsulates the logic of how source line resolver interacts with symbol
+ // supplier to symbolize stack frame and look up caller frame information
+ // (see stack_frame_symbolizer.h).
+ // frame_symbolizer MUST NOT be NULL (asserted).
+ Stackwalker(const SystemInfo* system_info,
+ MemoryRegion* memory,
+ const CodeModules* modules,
+ StackFrameSymbolizer* frame_symbolizer);
// This can be used to filter out potential return addresses when
// the stack walker resorts to stack scanning.
@@ -112,8 +108,8 @@ class Stackwalker {
template<typename InstructionType>
bool ScanForReturnAddress(InstructionType location_start,
- InstructionType *location_found,
- InstructionType *ip_found) {
+ InstructionType* location_found,
+ InstructionType* ip_found) {
const int kRASearchWords = 30;
return ScanForReturnAddress(location_start, location_found, ip_found,
kRASearchWords);
@@ -130,8 +126,8 @@ class Stackwalker {
// location in memory.
template<typename InstructionType>
bool ScanForReturnAddress(InstructionType location_start,
- InstructionType *location_found,
- InstructionType *ip_found,
+ InstructionType* location_found,
+ InstructionType* ip_found,
int searchwords) {
for (InstructionType location = location_start;
location <= location_start + searchwords * sizeof(InstructionType);
@@ -142,7 +138,6 @@ class Stackwalker {
if (modules_ && modules_->GetModuleForAddress(ip) &&
InstructionAddressSeemsValid(ip)) {
-
*ip_found = ip;
*location_found = location;
return true;
@@ -154,19 +149,19 @@ class Stackwalker {
// Information about the system that produced the minidump. Subclasses
// and the SymbolSupplier may find this information useful.
- const SystemInfo *system_info_;
+ const SystemInfo* system_info_;
// The stack memory to walk. Subclasses will require this region to
// get information from the stack.
- MemoryRegion *memory_;
+ MemoryRegion* memory_;
// A list of modules, for populating each StackFrame's module information.
// This field is optional and may be NULL.
- const CodeModules *modules_;
+ const CodeModules* modules_;
protected:
- // The SourceLineResolver implementation.
- SourceLineResolverInterface *resolver_;
+ // The StackFrameSymbolizer implementation.
+ StackFrameSymbolizer* frame_symbolizer_;
private:
// Obtains the context frame, the innermost called procedure in a stack
@@ -183,15 +178,7 @@ class Stackwalker {
// the end of the stack has been reached). GetCallerFrame allocates a new
// StackFrame (or StackFrame subclass), ownership of which is taken by
// the caller.
- virtual StackFrame* GetCallerFrame(const CallStack *stack) = 0;
-
- // The optional SymbolSupplier for resolving source line info.
- SymbolSupplier *supplier_;
-
- // A list of modules that we haven't found symbols for. We track
- // this in order to avoid repeatedly looking them up again within
- // one minidump.
- set<string> no_symbol_modules_;
+ virtual StackFrame* GetCallerFrame(const CallStack* stack) = 0;
// The maximum number of frames Stackwalker will walk through.
// This defaults to 1024 to prevent infinite loops.
diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc
index 814402be..a197cd10 100644
--- a/src/processor/minidump_processor.cc
+++ b/src/processor/minidump_processor.cc
@@ -36,6 +36,7 @@
#include "google_breakpad/processor/minidump.h"
#include "google_breakpad/processor/process_state.h"
#include "google_breakpad/processor/exploitability.h"
+#include "google_breakpad/processor/stack_frame_symbolizer.h"
#include "processor/logging.h"
#include "processor/scoped_ptr.h"
#include "processor/stackwalker_x86.h"
@@ -44,18 +45,29 @@ namespace google_breakpad {
MinidumpProcessor::MinidumpProcessor(SymbolSupplier *supplier,
SourceLineResolverInterface *resolver)
- : supplier_(supplier), resolver_(resolver),
+ : frame_symbolizer_(new StackFrameSymbolizer(supplier, resolver)),
+ own_frame_symbolizer_(true),
enable_exploitability_(false) {
}
MinidumpProcessor::MinidumpProcessor(SymbolSupplier *supplier,
SourceLineResolverInterface *resolver,
bool enable_exploitability)
- : supplier_(supplier), resolver_(resolver),
+ : frame_symbolizer_(new StackFrameSymbolizer(supplier, resolver)),
+ own_frame_symbolizer_(true),
enable_exploitability_(enable_exploitability) {
}
+MinidumpProcessor::MinidumpProcessor(StackFrameSymbolizer *frame_symbolizer,
+ bool enable_exploitability)
+ : frame_symbolizer_(frame_symbolizer),
+ own_frame_symbolizer_(false),
+ enable_exploitability_(enable_exploitability) {
+ assert(frame_symbolizer_);
+}
+
MinidumpProcessor::~MinidumpProcessor() {
+ if (own_frame_symbolizer_) delete frame_symbolizer_;
}
ProcessResult MinidumpProcessor::Process(
@@ -126,6 +138,10 @@ ProcessResult MinidumpProcessor::Process(
bool interrupted = false;
bool found_requesting_thread = false;
unsigned int thread_count = threads->thread_count();
+
+ // Reset frame_symbolizer_ at the beginning of stackwalk for each minidump.
+ frame_symbolizer_->Reset();
+
for (unsigned int thread_index = 0;
thread_index < thread_count;
++thread_index) {
@@ -208,8 +224,7 @@ ProcessResult MinidumpProcessor::Process(
context,
thread_memory,
process_state->modules_,
- supplier_,
- resolver_));
+ frame_symbolizer_));
if (!stackwalker.get()) {
BPLOG(ERROR) << "No stackwalker for " << thread_string;
return PROCESS_ERROR_NO_STACKWALKER_FOR_THREAD;
@@ -1160,7 +1175,8 @@ string MinidumpProcessor::GetAssertion(Minidump *dump) {
break;
default: {
char assertion_type[32];
- sprintf(assertion_type, "0x%08x", raw_assertion->type);
+ snprintf(assertion_type, sizeof(assertion_type),
+ "0x%08x", raw_assertion->type);
assertion_string = "Unknown assertion type ";
assertion_string += assertion_type;
break;
@@ -1184,7 +1200,7 @@ string MinidumpProcessor::GetAssertion(Minidump *dump) {
if (raw_assertion->line != 0) {
char assertion_line[32];
- sprintf(assertion_line, "%u", raw_assertion->line);
+ snprintf(assertion_line, sizeof(assertion_line), "%u", raw_assertion->line);
assertion_string.append(" at line ");
assertion_string.append(assertion_line);
}
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();
}
diff --git a/src/processor/stackwalker_amd64.cc b/src/processor/stackwalker_amd64.cc
index 5a9ddb19..12aa6333 100644
--- a/src/processor/stackwalker_amd64.cc
+++ b/src/processor/stackwalker_amd64.cc
@@ -89,13 +89,12 @@ StackwalkerAMD64::cfi_register_map_[] = {
StackFrameAMD64::CONTEXT_VALID_RIP, &MDRawContextAMD64::rip },
};
-StackwalkerAMD64::StackwalkerAMD64(const SystemInfo *system_info,
- const MDRawContextAMD64 *context,
- MemoryRegion *memory,
- const CodeModules *modules,
- SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver)
- : Stackwalker(system_info, memory, modules, supplier, resolver),
+StackwalkerAMD64::StackwalkerAMD64(const SystemInfo* system_info,
+ const MDRawContextAMD64* context,
+ MemoryRegion* memory,
+ const CodeModules* modules,
+ StackFrameSymbolizer* resolver_helper)
+ : Stackwalker(system_info, memory, modules, resolver_helper),
context_(context),
cfi_walker_(cfi_register_map_,
(sizeof(cfi_register_map_) / sizeof(cfi_register_map_[0]))) {
@@ -108,7 +107,7 @@ StackFrame* StackwalkerAMD64::GetContextFrame() {
return NULL;
}
- StackFrameAMD64 *frame = new StackFrameAMD64();
+ StackFrameAMD64* frame = new StackFrameAMD64();
// The instruction pointer is stored directly in a register, so pull it
// straight out of the CPU context structure.
@@ -120,10 +119,10 @@ StackFrame* StackwalkerAMD64::GetContextFrame() {
return frame;
}
-StackFrameAMD64 *StackwalkerAMD64::GetCallerByCFIFrameInfo(
- const vector<StackFrame *> &frames,
- CFIFrameInfo *cfi_frame_info) {
- StackFrameAMD64 *last_frame = static_cast<StackFrameAMD64*>(frames.back());
+StackFrameAMD64* StackwalkerAMD64::GetCallerByCFIFrameInfo(
+ const vector<StackFrame*> &frames,
+ CFIFrameInfo* cfi_frame_info) {
+ StackFrameAMD64* last_frame = static_cast<StackFrameAMD64*>(frames.back());
scoped_ptr<StackFrameAMD64> frame(new StackFrameAMD64());
if (!cfi_walker_
@@ -142,9 +141,9 @@ StackFrameAMD64 *StackwalkerAMD64::GetCallerByCFIFrameInfo(
return frame.release();
}
-StackFrameAMD64 *StackwalkerAMD64::GetCallerByStackScan(
- const vector<StackFrame *> &frames) {
- StackFrameAMD64 *last_frame = static_cast<StackFrameAMD64 *>(frames.back());
+StackFrameAMD64* StackwalkerAMD64::GetCallerByStackScan(
+ const vector<StackFrame*> &frames) {
+ StackFrameAMD64* last_frame = static_cast<StackFrameAMD64*>(frames.back());
u_int64_t last_rsp = last_frame->context.rsp;
u_int64_t caller_rip_address, caller_rip;
@@ -155,7 +154,7 @@ StackFrameAMD64 *StackwalkerAMD64::GetCallerByStackScan(
// Create a new stack frame (ownership will be transferred to the caller)
// and fill it in.
- StackFrameAMD64 *frame = new StackFrameAMD64();
+ StackFrameAMD64* frame = new StackFrameAMD64();
frame->trust = StackFrame::FRAME_TRUST_SCAN;
frame->context = last_frame->context;
@@ -191,19 +190,19 @@ StackFrameAMD64 *StackwalkerAMD64::GetCallerByStackScan(
return frame;
}
-StackFrame* StackwalkerAMD64::GetCallerFrame(const CallStack *stack) {
+StackFrame* StackwalkerAMD64::GetCallerFrame(const CallStack* stack) {
if (!memory_ || !stack) {
BPLOG(ERROR) << "Can't get caller frame without memory or stack";
return NULL;
}
- const vector<StackFrame *> &frames = *stack->frames();
- StackFrameAMD64 *last_frame = static_cast<StackFrameAMD64 *>(frames.back());
+ const vector<StackFrame*> &frames = *stack->frames();
+ StackFrameAMD64* last_frame = static_cast<StackFrameAMD64*>(frames.back());
scoped_ptr<StackFrameAMD64> new_frame;
// If we have DWARF CFI information, use it.
scoped_ptr<CFIFrameInfo> cfi_frame_info(
- resolver_ ? resolver_->FindCFIFrameInfo(last_frame) : NULL);
+ frame_symbolizer_->FindCFIFrameInfo(last_frame));
if (cfi_frame_info.get())
new_frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get()));
diff --git a/src/processor/stackwalker_amd64.h b/src/processor/stackwalker_amd64.h
index cde95208..3e41c123 100644
--- a/src/processor/stackwalker_amd64.h
+++ b/src/processor/stackwalker_amd64.h
@@ -38,6 +38,7 @@
#ifndef PROCESSOR_STACKWALKER_AMD64_H__
#define PROCESSOR_STACKWALKER_AMD64_H__
+#include <vector>
#include "google_breakpad/common/breakpad_types.h"
#include "google_breakpad/common/minidump_format.h"
@@ -55,12 +56,11 @@ class StackwalkerAMD64 : public Stackwalker {
// register state corresponding to the innermost called frame to be
// included in the stack. The other arguments are passed directly through
// to the base Stackwalker constructor.
- StackwalkerAMD64(const SystemInfo *system_info,
- const MDRawContextAMD64 *context,
- MemoryRegion *memory,
- const CodeModules *modules,
- SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver);
+ StackwalkerAMD64(const SystemInfo* system_info,
+ const MDRawContextAMD64* context,
+ MemoryRegion* memory,
+ const CodeModules* modules,
+ StackFrameSymbolizer* frame_symbolizer);
private:
// A STACK CFI-driven frame walker for the AMD64
@@ -69,21 +69,21 @@ class StackwalkerAMD64 : public Stackwalker {
// Implementation of Stackwalker, using amd64 context (stack pointer in %rsp,
// stack base in %rbp) and stack conventions (saved stack pointer at 0(%rbp))
virtual StackFrame* GetContextFrame();
- virtual StackFrame* GetCallerFrame(const CallStack *stack);
+ virtual StackFrame* GetCallerFrame(const CallStack* stack);
// Use cfi_frame_info (derived from STACK CFI records) to construct
// the frame that called frames.back(). The caller takes ownership
// of the returned frame. Return NULL on failure.
- StackFrameAMD64 *GetCallerByCFIFrameInfo(const vector<StackFrame *> &frames,
- CFIFrameInfo *cfi_frame_info);
+ StackFrameAMD64* GetCallerByCFIFrameInfo(const vector<StackFrame*> &frames,
+ CFIFrameInfo* cfi_frame_info);
// Scan the stack for plausible return addresses. The caller takes ownership
- // of the returned frame. Return NULL on failure.
- StackFrameAMD64 *GetCallerByStackScan(const vector<StackFrame *> &frames);
+ // of the returned frame. Return NULL on failure.
+ StackFrameAMD64* GetCallerByStackScan(const vector<StackFrame*> &frames);
// Stores the CPU context corresponding to the innermost stack frame to
// be returned by GetContextFrame.
- const MDRawContextAMD64 *context_;
+ const MDRawContextAMD64* context_;
// Our register map, for cfi_walker_.
static const CFIWalker::RegisterSet cfi_register_map_[];
diff --git a/src/processor/stackwalker_amd64_unittest.cc b/src/processor/stackwalker_amd64_unittest.cc
index f3723c0c..1721b8cb 100644
--- a/src/processor/stackwalker_amd64_unittest.cc
+++ b/src/processor/stackwalker_amd64_unittest.cc
@@ -31,8 +31,8 @@
// stackwalker_amd64_unittest.cc: Unit tests for StackwalkerAMD64 class.
-#include <string>
#include <string.h>
+#include <string>
#include <vector>
#include "breakpad_googletest_includes.h"
@@ -48,6 +48,7 @@
using google_breakpad::BasicSourceLineResolver;
using google_breakpad::CallStack;
+using google_breakpad::StackFrameSymbolizer;
using google_breakpad::StackFrame;
using google_breakpad::StackFrameAMD64;
using google_breakpad::StackwalkerAMD64;
@@ -112,7 +113,7 @@ class StackwalkerAMD64Fixture {
for (size_t i = 0; i < sizeof(*raw_context); i++)
reinterpret_cast<u_int8_t *>(raw_context)[i] = (x += 17);
}
-
+
SystemInfo system_info;
MDRawContextAMD64 raw_context;
Section stack_section;
@@ -138,8 +139,9 @@ TEST_F(SanityCheck, NoResolver) {
raw_context.rip = 0x40000000c0000200ULL;
raw_context.rbp = 0x8000000080000000ULL;
+ StackFrameSymbolizer frame_symbolizer(NULL, NULL);
StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
- NULL, NULL);
+ &frame_symbolizer);
// This should succeed even without a resolver or supplier.
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
@@ -158,8 +160,9 @@ TEST_F(GetContextFrame, Simple) {
raw_context.rip = 0x40000000c0000200ULL;
raw_context.rbp = 0x8000000080000000ULL;
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_GE(1U, frames->size());
@@ -207,13 +210,14 @@ TEST_F(GetCallerFrame, ScanWithoutSymbols) {
.Append(32, 0); // end of stack
RegionFromSection();
-
+
raw_context.rip = 0x40000000c0000200ULL;
raw_context.rbp = frame1_rbp.Value();
raw_context.rsp = stack_section.start().Value();
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(3U, frames->size());
@@ -267,7 +271,7 @@ TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
.Append(32, 0) // end of stack
.Mark(&frame1_rbp);
RegionFromSection();
-
+
raw_context.rip = 0x40000000c0000200ULL;
raw_context.rbp = frame1_rbp.Value();
raw_context.rsp = stack_section.start().Value();
@@ -279,8 +283,9 @@ TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
// The calling frame's function.
"FUNC 100 400 10 echidna\n");
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
@@ -343,8 +348,9 @@ TEST_F(GetCallerFrame, CallerPushedRBP) {
// The calling frame's function.
"FUNC 100 400 10 yeti\n");
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
@@ -418,8 +424,9 @@ struct CFIFixture: public StackwalkerAMD64Fixture {
RegionFromSection();
raw_context.rsp = stack_section.start().Value();
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
diff --git a/src/processor/stackwalker_arm.cc b/src/processor/stackwalker_arm.cc
index 0a3c522d..3beaa449 100644
--- a/src/processor/stackwalker_arm.cc
+++ b/src/processor/stackwalker_arm.cc
@@ -33,6 +33,8 @@
//
// Author: Mark Mentovai, Ted Mielczarek, Jim Blandy
+#include <vector>
+
#include "google_breakpad/processor/call_stack.h"
#include "google_breakpad/processor/memory_region.h"
#include "google_breakpad/processor/source_line_resolver_interface.h"
@@ -45,14 +47,13 @@
namespace google_breakpad {
-StackwalkerARM::StackwalkerARM(const SystemInfo *system_info,
- const MDRawContextARM *context,
+StackwalkerARM::StackwalkerARM(const SystemInfo* system_info,
+ const MDRawContextARM* context,
int fp_register,
- MemoryRegion *memory,
- const CodeModules *modules,
- SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver)
- : Stackwalker(system_info, memory, modules, supplier, resolver),
+ MemoryRegion* memory,
+ const CodeModules* modules,
+ StackFrameSymbolizer* resolver_helper)
+ : Stackwalker(system_info, memory, modules, resolver_helper),
context_(context), fp_register_(fp_register),
context_frame_validity_(StackFrameARM::CONTEXT_VALID_ALL) { }
@@ -63,7 +64,7 @@ StackFrame* StackwalkerARM::GetContextFrame() {
return NULL;
}
- StackFrameARM *frame = new StackFrameARM();
+ StackFrameARM* frame = new StackFrameARM();
// The instruction pointer is stored directly in a register (r15), so pull it
// straight out of the CPU context structure.
@@ -75,12 +76,12 @@ StackFrame* StackwalkerARM::GetContextFrame() {
return frame;
}
-StackFrameARM *StackwalkerARM::GetCallerByCFIFrameInfo(
- const vector<StackFrame *> &frames,
- CFIFrameInfo *cfi_frame_info) {
- StackFrameARM *last_frame = static_cast<StackFrameARM *>(frames.back());
+StackFrameARM* StackwalkerARM::GetCallerByCFIFrameInfo(
+ const vector<StackFrame*> &frames,
+ CFIFrameInfo* cfi_frame_info) {
+ StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back());
- static const char *register_names[] = {
+ static const char* register_names[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
@@ -121,7 +122,7 @@ StackFrameARM *StackwalkerARM::GetCallerByCFIFrameInfo(
}
}
// If the CFI doesn't recover the PC explicitly, then use .ra.
- if (! (frame->context_validity & StackFrameARM::CONTEXT_VALID_PC)) {
+ if (!(frame->context_validity & StackFrameARM::CONTEXT_VALID_PC)) {
CFIFrameInfo::RegisterValueMap<u_int32_t>::iterator entry =
caller_registers.find(".ra");
if (entry != caller_registers.end()) {
@@ -140,7 +141,7 @@ StackFrameARM *StackwalkerARM::GetCallerByCFIFrameInfo(
}
}
// If the CFI doesn't recover the SP explicitly, then use .cfa.
- if (! (frame->context_validity & StackFrameARM::CONTEXT_VALID_SP)) {
+ if (!(frame->context_validity & StackFrameARM::CONTEXT_VALID_SP)) {
CFIFrameInfo::RegisterValueMap<u_int32_t>::iterator entry =
caller_registers.find(".cfa");
if (entry != caller_registers.end()) {
@@ -159,9 +160,9 @@ StackFrameARM *StackwalkerARM::GetCallerByCFIFrameInfo(
return frame.release();
}
-StackFrameARM *StackwalkerARM::GetCallerByStackScan(
- const vector<StackFrame *> &frames) {
- StackFrameARM *last_frame = static_cast<StackFrameARM *>(frames.back());
+StackFrameARM* StackwalkerARM::GetCallerByStackScan(
+ const vector<StackFrame*> &frames) {
+ StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back());
u_int32_t last_sp = last_frame->context.iregs[MD_CONTEXT_ARM_REG_SP];
u_int32_t caller_sp, caller_pc;
@@ -177,7 +178,7 @@ StackFrameARM *StackwalkerARM::GetCallerByStackScan(
// Create a new stack frame (ownership will be transferred to the caller)
// and fill it in.
- StackFrameARM *frame = new StackFrameARM();
+ StackFrameARM* frame = new StackFrameARM();
frame->trust = StackFrame::FRAME_TRUST_SCAN;
frame->context = last_frame->context;
@@ -189,9 +190,9 @@ StackFrameARM *StackwalkerARM::GetCallerByStackScan(
return frame;
}
-StackFrameARM *StackwalkerARM::GetCallerByFramePointer(
- const vector<StackFrame *> &frames) {
- StackFrameARM *last_frame = static_cast<StackFrameARM *>(frames.back());
+StackFrameARM* StackwalkerARM::GetCallerByFramePointer(
+ const vector<StackFrame*> &frames) {
+ StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back());
if (!(last_frame->context_validity &
StackFrameARM::RegisterValidFlag(fp_register_))) {
@@ -219,7 +220,7 @@ StackFrameARM *StackwalkerARM::GetCallerByFramePointer(
// Create a new stack frame (ownership will be transferred to the caller)
// and fill it in.
- StackFrameARM *frame = new StackFrameARM();
+ StackFrameARM* frame = new StackFrameARM();
frame->trust = StackFrame::FRAME_TRUST_FP;
frame->context = last_frame->context;
@@ -235,19 +236,19 @@ StackFrameARM *StackwalkerARM::GetCallerByFramePointer(
return frame;
}
-StackFrame* StackwalkerARM::GetCallerFrame(const CallStack *stack) {
+StackFrame* StackwalkerARM::GetCallerFrame(const CallStack* stack) {
if (!memory_ || !stack) {
BPLOG(ERROR) << "Can't get caller frame without memory or stack";
return NULL;
}
- const vector<StackFrame *> &frames = *stack->frames();
- StackFrameARM *last_frame = static_cast<StackFrameARM *>(frames.back());
+ const vector<StackFrame*> &frames = *stack->frames();
+ StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back());
scoped_ptr<StackFrameARM> frame;
// See if there is DWARF call frame information covering this address.
scoped_ptr<CFIFrameInfo> cfi_frame_info(
- resolver_ ? resolver_->FindCFIFrameInfo(last_frame) : NULL);
+ frame_symbolizer_->FindCFIFrameInfo(last_frame));
if (cfi_frame_info.get())
frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get()));
diff --git a/src/processor/stackwalker_arm.h b/src/processor/stackwalker_arm.h
index 24fc60dd..eb480156 100644
--- a/src/processor/stackwalker_arm.h
+++ b/src/processor/stackwalker_arm.h
@@ -54,13 +54,12 @@ class StackwalkerARM : public Stackwalker {
// register state corresponding to the innermost called frame to be
// included in the stack. The other arguments are passed directly through
// to the base Stackwalker constructor.
- StackwalkerARM(const SystemInfo *system_info,
- const MDRawContextARM *context,
+ StackwalkerARM(const SystemInfo* system_info,
+ const MDRawContextARM* context,
int fp_register,
- MemoryRegion *memory,
- const CodeModules *modules,
- SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver);
+ MemoryRegion* memory,
+ const CodeModules* modules,
+ StackFrameSymbolizer* frame_symbolizer);
// Change the context validity mask of the frame returned by
// GetContextFrame to VALID. This is only for use by unit tests; the
@@ -70,25 +69,25 @@ class StackwalkerARM : public Stackwalker {
private:
// Implementation of Stackwalker, using arm context and stack conventions.
virtual StackFrame* GetContextFrame();
- virtual StackFrame* GetCallerFrame(const CallStack *stack);
+ virtual StackFrame* GetCallerFrame(const CallStack* stack);
// Use cfi_frame_info (derived from STACK CFI records) to construct
// the frame that called frames.back(). The caller takes ownership
// of the returned frame. Return NULL on failure.
- StackFrameARM *GetCallerByCFIFrameInfo(const vector<StackFrame *> &frames,
- CFIFrameInfo *cfi_frame_info);
+ StackFrameARM* GetCallerByCFIFrameInfo(const vector<StackFrame*> &frames,
+ CFIFrameInfo* cfi_frame_info);
// Use the frame pointer. The caller takes ownership of the returned frame.
// Return NULL on failure.
- StackFrameARM *GetCallerByFramePointer(const vector<StackFrame *> &frames);
+ StackFrameARM* GetCallerByFramePointer(const vector<StackFrame*> &frames);
// Scan the stack for plausible return addresses. The caller takes ownership
// of the returned frame. Return NULL on failure.
- StackFrameARM *GetCallerByStackScan(const vector<StackFrame *> &frames);
+ StackFrameARM* GetCallerByStackScan(const vector<StackFrame*> &frames);
// Stores the CPU context corresponding to the youngest stack frame, to
// be returned by GetContextFrame.
- const MDRawContextARM *context_;
+ const MDRawContextARM* context_;
// The register to use a as frame pointer. The value is -1 if frame pointer
// cannot be used.
diff --git a/src/processor/stackwalker_arm_unittest.cc b/src/processor/stackwalker_arm_unittest.cc
index 10772ba4..88517b77 100644
--- a/src/processor/stackwalker_arm_unittest.cc
+++ b/src/processor/stackwalker_arm_unittest.cc
@@ -31,8 +31,8 @@
// stackwalker_arm_unittest.cc: Unit tests for StackwalkerARM class.
-#include <string>
#include <string.h>
+#include <string>
#include <vector>
#include "breakpad_googletest_includes.h"
@@ -49,6 +49,7 @@
using google_breakpad::BasicSourceLineResolver;
using google_breakpad::CallStack;
+using google_breakpad::StackFrameSymbolizer;
using google_breakpad::StackFrame;
using google_breakpad::StackFrameARM;
using google_breakpad::StackwalkerARM;
@@ -134,8 +135,9 @@ TEST_F(SanityCheck, NoResolver) {
// Since we have no call frame information, and all unwinding
// requires call frame information, the stack walk will end after
// the first frame.
+ StackFrameSymbolizer frame_symbolizer(NULL, NULL);
StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
- NULL, NULL);
+ &frame_symbolizer);
// This should succeed even without a resolver or supplier.
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
@@ -152,8 +154,9 @@ TEST_F(GetContextFrame, Simple) {
// Since we have no call frame information, and all unwinding
// requires call frame information, the stack walk will end after
// the first frame.
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(1U, frames->size());
@@ -199,8 +202,9 @@ TEST_F(GetCallerFrame, ScanWithoutSymbols) {
raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(3U, frames->size());
@@ -262,8 +266,9 @@ TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
// The calling frame's function.
"FUNC 100 400 10 marsupial\n");
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
@@ -372,8 +377,9 @@ struct CFIFixture: public StackwalkerARMFixture {
RegionFromSection();
raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region,
- &modules, &supplier, &resolver);
+ &modules, &frame_symbolizer);
walker.SetContextFrameValidity(context_frame_validity);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
@@ -564,8 +570,9 @@ TEST_F(CFI, RejectBackwards) {
raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40006000;
raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000;
raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = 0x40005510;
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(1U, frames->size());
@@ -575,8 +582,9 @@ TEST_F(CFI, RejectBackwards) {
TEST_F(CFI, RejectBadExpressions) {
raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40007000;
raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000;
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(1U, frames->size());
@@ -631,8 +639,9 @@ TEST_F(GetFramesByFramePointer, OnlyFramePointer) {
raw_context.iregs[MD_CONTEXT_ARM_REG_IOS_FP] = frame1_fp.Value();
raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP,
- &stack_region, &modules, &supplier, &resolver);
+ &stack_region, &modules, &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
@@ -720,8 +729,9 @@ TEST_F(GetFramesByFramePointer, FramePointerAndCFI) {
raw_context.iregs[MD_CONTEXT_ARM_REG_IOS_FP] = frame1_fp.Value();
raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP,
- &stack_region, &modules, &supplier, &resolver);
+ &stack_region, &modules, &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
diff --git a/src/processor/stackwalker_ppc.cc b/src/processor/stackwalker_ppc.cc
index 4d9a6282..6359e737 100644
--- a/src/processor/stackwalker_ppc.cc
+++ b/src/processor/stackwalker_ppc.cc
@@ -43,13 +43,12 @@
namespace google_breakpad {
-StackwalkerPPC::StackwalkerPPC(const SystemInfo *system_info,
- const MDRawContextPPC *context,
- MemoryRegion *memory,
- const CodeModules *modules,
- SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver)
- : Stackwalker(system_info, memory, modules, supplier, resolver),
+StackwalkerPPC::StackwalkerPPC(const SystemInfo* system_info,
+ const MDRawContextPPC* context,
+ MemoryRegion* memory,
+ const CodeModules* modules,
+ StackFrameSymbolizer* resolver_helper)
+ : Stackwalker(system_info, memory, modules, resolver_helper),
context_(context) {
if (memory_->GetBase() + memory_->GetSize() - 1 > 0xffffffff) {
// This implementation only covers 32-bit ppc CPUs. The limits of the
@@ -69,7 +68,7 @@ StackFrame* StackwalkerPPC::GetContextFrame() {
return NULL;
}
- StackFramePPC *frame = new StackFramePPC();
+ StackFramePPC* frame = new StackFramePPC();
// The instruction pointer is stored directly in a register, so pull it
// straight out of the CPU context structure.
@@ -82,7 +81,7 @@ StackFrame* StackwalkerPPC::GetContextFrame() {
}
-StackFrame* StackwalkerPPC::GetCallerFrame(const CallStack *stack) {
+StackFrame* StackwalkerPPC::GetCallerFrame(const CallStack* stack) {
if (!memory_ || !stack) {
BPLOG(ERROR) << "Can't get caller frame without memory or stack";
return NULL;
@@ -97,7 +96,7 @@ StackFrame* StackwalkerPPC::GetCallerFrame(const CallStack *stack) {
// frame pointer, and what is typically thought of as the frame pointer on
// an x86 is usually referred to as the stack pointer on a ppc.
- StackFramePPC *last_frame = static_cast<StackFramePPC*>(
+ StackFramePPC* last_frame = static_cast<StackFramePPC*>(
stack->frames()->back());
// A caller frame must reside higher in memory than its callee frames.
@@ -121,7 +120,7 @@ StackFrame* StackwalkerPPC::GetCallerFrame(const CallStack *stack) {
return NULL;
}
- StackFramePPC *frame = new StackFramePPC();
+ StackFramePPC* frame = new StackFramePPC();
frame->context = last_frame->context;
frame->context.srr0 = instruction;
diff --git a/src/processor/stackwalker_ppc.h b/src/processor/stackwalker_ppc.h
index bfbb4f82..0c989578 100644
--- a/src/processor/stackwalker_ppc.h
+++ b/src/processor/stackwalker_ppc.h
@@ -53,23 +53,22 @@ class StackwalkerPPC : public Stackwalker {
// register state corresponding to the innermost called frame to be
// included in the stack. The other arguments are passed directly through
// to the base Stackwalker constructor.
- StackwalkerPPC(const SystemInfo *system_info,
- const MDRawContextPPC *context,
- MemoryRegion *memory,
- const CodeModules *modules,
- SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver);
+ StackwalkerPPC(const SystemInfo* system_info,
+ const MDRawContextPPC* context,
+ MemoryRegion* memory,
+ const CodeModules* modules,
+ StackFrameSymbolizer* frame_symbolizer);
private:
// Implementation of Stackwalker, using ppc context (stack pointer in %r1,
// saved program counter in %srr0) and stack conventions (saved stack
// pointer at 0(%r1), return address at 8(0(%r1)).
virtual StackFrame* GetContextFrame();
- virtual StackFrame* GetCallerFrame(const CallStack *stack);
+ virtual StackFrame* GetCallerFrame(const CallStack* stack);
// Stores the CPU context corresponding to the innermost stack frame to
// be returned by GetContextFrame.
- const MDRawContextPPC *context_;
+ const MDRawContextPPC* context_;
};
diff --git a/src/processor/stackwalker_sparc.cc b/src/processor/stackwalker_sparc.cc
index 2e819a69..ac356baa 100644
--- a/src/processor/stackwalker_sparc.cc
+++ b/src/processor/stackwalker_sparc.cc
@@ -43,13 +43,12 @@
namespace google_breakpad {
-StackwalkerSPARC::StackwalkerSPARC(const SystemInfo *system_info,
- const MDRawContextSPARC *context,
- MemoryRegion *memory,
- const CodeModules *modules,
- SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver)
- : Stackwalker(system_info, memory, modules, supplier, resolver),
+StackwalkerSPARC::StackwalkerSPARC(const SystemInfo* system_info,
+ const MDRawContextSPARC* context,
+ MemoryRegion* memory,
+ const CodeModules* modules,
+ StackFrameSymbolizer* resolver_helper)
+ : Stackwalker(system_info, memory, modules, resolver_helper),
context_(context) {
}
@@ -60,7 +59,7 @@ StackFrame* StackwalkerSPARC::GetContextFrame() {
return NULL;
}
- StackFrameSPARC *frame = new StackFrameSPARC();
+ StackFrameSPARC* frame = new StackFrameSPARC();
// The instruction pointer is stored directly in a register, so pull it
// straight out of the CPU context structure.
@@ -73,13 +72,13 @@ StackFrame* StackwalkerSPARC::GetContextFrame() {
}
-StackFrame* StackwalkerSPARC::GetCallerFrame(const CallStack *stack) {
+StackFrame* StackwalkerSPARC::GetCallerFrame(const CallStack* stack) {
if (!memory_ || !stack) {
BPLOG(ERROR) << "Can't get caller frame without memory or stack";
return NULL;
}
- StackFrameSPARC *last_frame = static_cast<StackFrameSPARC*>(
+ StackFrameSPARC* last_frame = static_cast<StackFrameSPARC*>(
stack->frames()->back());
// new: caller
@@ -87,7 +86,7 @@ StackFrame* StackwalkerSPARC::GetCallerFrame(const CallStack *stack) {
// %fp, %i6 and g_r[30] is the same, see minidump_format.h
// %sp, %o6 and g_r[14] is the same, see minidump_format.h
// %sp_new = %fp_old
- // %fp_new = *(%fp_old + 32 + 32 - 8), where the callee's %i6
+ // %fp_new = *(%fp_old + 32 + 32 - 8), where the callee's %i6
// %pc_new = *(%fp_old + 32 + 32 - 4) + 8
// which is callee's %i7 plus 8
@@ -111,14 +110,14 @@ StackFrame* StackwalkerSPARC::GetCallerFrame(const CallStack *stack) {
return NULL;
}
- StackFrameSPARC *frame = new StackFrameSPARC();
+ StackFrameSPARC* frame = new StackFrameSPARC();
frame->context = last_frame->context;
frame->context.g_r[14] = stack_pointer;
frame->context.g_r[30] = stack_base;
-
+
// frame->context.pc is the return address, which is 2 instruction
- // past the branch that caused us to arrive at the callee, which are
+ // past the branch that caused us to arrive at the callee, which are
// a CALL instruction then a NOP instruction.
// frame_ppc->instruction to 8 less than that. Since all sparc
// instructions are 4 bytes wide, this is the address of the branch
@@ -131,7 +130,7 @@ StackFrame* StackwalkerSPARC::GetCallerFrame(const CallStack *stack) {
StackFrameSPARC::CONTEXT_VALID_SP |
StackFrameSPARC::CONTEXT_VALID_FP;
frame->trust = StackFrame::FRAME_TRUST_FP;
-
+
return frame;
}
diff --git a/src/processor/stackwalker_sparc.h b/src/processor/stackwalker_sparc.h
index ad41aeab..53fbc843 100644
--- a/src/processor/stackwalker_sparc.h
+++ b/src/processor/stackwalker_sparc.h
@@ -53,22 +53,21 @@ class StackwalkerSPARC : public Stackwalker {
// register state corresponding to the innermost called frame to be
// included in the stack. The other arguments are passed directly through
// to the base Stackwalker constructor.
- StackwalkerSPARC(const SystemInfo *system_info,
- const MDRawContextSPARC *context,
- MemoryRegion *memory,
- const CodeModules *modules,
- SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver);
+ StackwalkerSPARC(const SystemInfo* system_info,
+ const MDRawContextSPARC* context,
+ MemoryRegion* memory,
+ const CodeModules* modules,
+ StackFrameSymbolizer* frame_symbolizer);
private:
// Implementation of Stackwalker, using sparc context (%fp, %sp, %pc) and
// stack conventions
virtual StackFrame* GetContextFrame();
- virtual StackFrame* GetCallerFrame(const CallStack *stack);
+ virtual StackFrame* GetCallerFrame(const CallStack* stack);
// Stores the CPU context corresponding to the innermost stack frame to
// be returned by GetContextFrame.
- const MDRawContextSPARC *context_;
+ const MDRawContextSPARC* context_;
};
diff --git a/src/processor/stackwalker_x86.cc b/src/processor/stackwalker_x86.cc
index ba3b8396..4ee5beed 100644
--- a/src/processor/stackwalker_x86.cc
+++ b/src/processor/stackwalker_x86.cc
@@ -33,8 +33,7 @@
//
// Author: Mark Mentovai
-
-#include "processor/postfix_evaluator-inl.h"
+#include <string>
#include "google_breakpad/processor/call_stack.h"
#include "google_breakpad/processor/code_modules.h"
@@ -42,6 +41,7 @@
#include "google_breakpad/processor/source_line_resolver_interface.h"
#include "google_breakpad/processor/stack_frame_cpu.h"
#include "processor/logging.h"
+#include "processor/postfix_evaluator-inl.h"
#include "processor/scoped_ptr.h"
#include "processor/stackwalker_x86.h"
#include "processor/windows_frame_info.h"
@@ -77,13 +77,12 @@ StackwalkerX86::cfi_register_map_[] = {
StackFrameX86::CONTEXT_VALID_EDI, &MDRawContextX86::edi },
};
-StackwalkerX86::StackwalkerX86(const SystemInfo *system_info,
- const MDRawContextX86 *context,
- MemoryRegion *memory,
- const CodeModules *modules,
- SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver)
- : Stackwalker(system_info, memory, modules, supplier, resolver),
+StackwalkerX86::StackwalkerX86(const SystemInfo* system_info,
+ const MDRawContextX86* context,
+ MemoryRegion* memory,
+ const CodeModules* modules,
+ StackFrameSymbolizer* resolver_helper)
+ : Stackwalker(system_info, memory, modules, resolver_helper),
context_(context),
cfi_walker_(cfi_register_map_,
(sizeof(cfi_register_map_) / sizeof(cfi_register_map_[0]))) {
@@ -106,13 +105,13 @@ StackFrameX86::~StackFrameX86() {
cfi_frame_info = NULL;
}
-StackFrame *StackwalkerX86::GetContextFrame() {
+StackFrame* StackwalkerX86::GetContextFrame() {
if (!context_ || !memory_) {
BPLOG(ERROR) << "Can't get context frame without context or memory";
return NULL;
}
- StackFrameX86 *frame = new StackFrameX86();
+ StackFrameX86* frame = new StackFrameX86();
// The instruction pointer is stored directly in a register, so pull it
// straight out of the CPU context structure.
@@ -124,12 +123,12 @@ StackFrame *StackwalkerX86::GetContextFrame() {
return frame;
}
-StackFrameX86 *StackwalkerX86::GetCallerByWindowsFrameInfo(
- const vector<StackFrame *> &frames,
- WindowsFrameInfo *last_frame_info) {
+StackFrameX86* StackwalkerX86::GetCallerByWindowsFrameInfo(
+ const vector<StackFrame*> &frames,
+ WindowsFrameInfo* last_frame_info) {
StackFrame::FrameTrust trust = StackFrame::FRAME_TRUST_NONE;
- StackFrameX86 *last_frame = static_cast<StackFrameX86 *>(frames.back());
+ StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back());
// Save the stack walking info we found, in case we need it later to
// find the callee of the frame we're constructing now.
@@ -176,9 +175,9 @@ StackFrameX86 *StackwalkerX86::GetCallerByWindowsFrameInfo(
u_int32_t last_frame_callee_parameter_size = 0;
int frames_already_walked = frames.size();
if (frames_already_walked >= 2) {
- const StackFrameX86 *last_frame_callee
- = static_cast<StackFrameX86 *>(frames[frames_already_walked - 2]);
- WindowsFrameInfo *last_frame_callee_info
+ const StackFrameX86* last_frame_callee
+ = static_cast<StackFrameX86*>(frames[frames_already_walked - 2]);
+ WindowsFrameInfo* last_frame_callee_info
= last_frame_callee->windows_frame_info;
if (last_frame_callee_info &&
(last_frame_callee_info->valid
@@ -210,7 +209,7 @@ StackFrameX86 *StackwalkerX86::GetCallerByWindowsFrameInfo(
last_frame_info->saved_register_size;
u_int32_t raSearchStartOld = raSearchStart;
- u_int32_t found = 0; // dummy value
+ u_int32_t found = 0; // dummy value
// Scan up to three words above the calculated search value, in case
// the stack was aligned to a quadword boundary.
if (ScanForReturnAddress(raSearchStart, &raSearchStart, &found, 3) &&
@@ -419,7 +418,7 @@ StackFrameX86 *StackwalkerX86::GetCallerByWindowsFrameInfo(
// Create a new stack frame (ownership will be transferred to the caller)
// and fill it in.
- StackFrameX86 *frame = new StackFrameX86();
+ StackFrameX86* frame = new StackFrameX86();
frame->trust = trust;
frame->context = last_frame->context;
@@ -448,10 +447,10 @@ StackFrameX86 *StackwalkerX86::GetCallerByWindowsFrameInfo(
return frame;
}
-StackFrameX86 *StackwalkerX86::GetCallerByCFIFrameInfo(
+StackFrameX86* StackwalkerX86::GetCallerByCFIFrameInfo(
const vector<StackFrame*> &frames,
- CFIFrameInfo *cfi_frame_info) {
- StackFrameX86 *last_frame = static_cast<StackFrameX86*>(frames.back());
+ CFIFrameInfo* cfi_frame_info) {
+ StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back());
last_frame->cfi_frame_info = cfi_frame_info;
scoped_ptr<StackFrameX86> frame(new StackFrameX86());
@@ -460,7 +459,7 @@ StackFrameX86 *StackwalkerX86::GetCallerByCFIFrameInfo(
last_frame->context, last_frame->context_validity,
&frame->context, &frame->context_validity))
return NULL;
-
+
// Make sure we recovered all the essentials.
static const int essentials = (StackFrameX86::CONTEXT_VALID_EIP
| StackFrameX86::CONTEXT_VALID_ESP
@@ -473,10 +472,10 @@ StackFrameX86 *StackwalkerX86::GetCallerByCFIFrameInfo(
return frame.release();
}
-StackFrameX86 *StackwalkerX86::GetCallerByEBPAtBase(
- const vector<StackFrame *> &frames) {
+StackFrameX86* StackwalkerX86::GetCallerByEBPAtBase(
+ const vector<StackFrame*> &frames) {
StackFrame::FrameTrust trust;
- StackFrameX86 *last_frame = static_cast<StackFrameX86 *>(frames.back());
+ StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back());
u_int32_t last_esp = last_frame->context.esp;
u_int32_t last_ebp = last_frame->context.ebp;
@@ -532,7 +531,7 @@ StackFrameX86 *StackwalkerX86::GetCallerByEBPAtBase(
// Create a new stack frame (ownership will be transferred to the caller)
// and fill it in.
- StackFrameX86 *frame = new StackFrameX86();
+ StackFrameX86* frame = new StackFrameX86();
frame->trust = trust;
frame->context = last_frame->context;
@@ -546,26 +545,26 @@ StackFrameX86 *StackwalkerX86::GetCallerByEBPAtBase(
return frame;
}
-StackFrame *StackwalkerX86::GetCallerFrame(const CallStack *stack) {
+StackFrame* StackwalkerX86::GetCallerFrame(const CallStack* stack) {
if (!memory_ || !stack) {
BPLOG(ERROR) << "Can't get caller frame without memory or stack";
return NULL;
}
- const vector<StackFrame *> &frames = *stack->frames();
- StackFrameX86 *last_frame = static_cast<StackFrameX86 *>(frames.back());
+ const vector<StackFrame*> &frames = *stack->frames();
+ StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back());
scoped_ptr<StackFrameX86> new_frame;
// If the resolver has Windows stack walking information, use that.
- WindowsFrameInfo *windows_frame_info
- = resolver_ ? resolver_->FindWindowsFrameInfo(last_frame) : NULL;
+ WindowsFrameInfo* windows_frame_info
+ = frame_symbolizer_->FindWindowsFrameInfo(last_frame);
if (windows_frame_info)
new_frame.reset(GetCallerByWindowsFrameInfo(frames, windows_frame_info));
// If the resolver has DWARF CFI information, use that.
if (!new_frame.get()) {
- CFIFrameInfo *cfi_frame_info =
- resolver_ ? resolver_->FindCFIFrameInfo(last_frame) : NULL;
+ CFIFrameInfo* cfi_frame_info =
+ frame_symbolizer_->FindCFIFrameInfo(last_frame);
if (cfi_frame_info)
new_frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info));
}
@@ -577,7 +576,7 @@ StackFrame *StackwalkerX86::GetCallerFrame(const CallStack *stack) {
// If nothing worked, tell the caller.
if (!new_frame.get())
return NULL;
-
+
// Treat an instruction address of 0 as end-of-stack.
if (new_frame->context.eip == 0)
return NULL;
diff --git a/src/processor/stackwalker_x86.h b/src/processor/stackwalker_x86.h
index 9c56ae80..410a473d 100644
--- a/src/processor/stackwalker_x86.h
+++ b/src/processor/stackwalker_x86.h
@@ -1,4 +1,4 @@
-// -*- mode: c++ -*-
+// -*- mode: c++ -*-
// Copyright (c) 2010 Google Inc.
// All rights reserved.
@@ -40,6 +40,7 @@
#ifndef PROCESSOR_STACKWALKER_X86_H__
#define PROCESSOR_STACKWALKER_X86_H__
+#include <vector>
#include "google_breakpad/common/breakpad_types.h"
#include "google_breakpad/common/minidump_format.h"
@@ -58,12 +59,11 @@ class StackwalkerX86 : public Stackwalker {
// register state corresponding to the innermost called frame to be
// included in the stack. The other arguments are passed directly through
// to the base Stackwalker constructor.
- StackwalkerX86(const SystemInfo *system_info,
- const MDRawContextX86 *context,
- MemoryRegion *memory,
- const CodeModules *modules,
- SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver);
+ StackwalkerX86(const SystemInfo* system_info,
+ const MDRawContextX86* context,
+ MemoryRegion* memory,
+ const CodeModules* modules,
+ StackFrameSymbolizer* frame_symbolizer);
private:
// A STACK CFI-driven frame walker for the X86.
@@ -73,32 +73,32 @@ class StackwalkerX86 : public Stackwalker {
// stack conventions (saved %ebp at [%ebp], saved %eip at 4[%ebp], or
// alternate conventions as guided by any WindowsFrameInfo available for the
// code in question.).
- virtual StackFrame *GetContextFrame();
- virtual StackFrame *GetCallerFrame(const CallStack *stack);
+ virtual StackFrame* GetContextFrame();
+ virtual StackFrame* GetCallerFrame(const CallStack* stack);
// Use windows_frame_info (derived from STACK WIN and FUNC records)
// to construct the frame that called frames.back(). The caller
// takes ownership of the returned frame. Return NULL on failure.
- StackFrameX86 *GetCallerByWindowsFrameInfo(
+ StackFrameX86* GetCallerByWindowsFrameInfo(
const vector<StackFrame*> &frames,
- WindowsFrameInfo *windows_frame_info);
+ WindowsFrameInfo* windows_frame_info);
// Use cfi_frame_info (derived from STACK CFI records) to construct
// the frame that called frames.back(). The caller takes ownership
// of the returned frame. Return NULL on failure.
- StackFrameX86 *GetCallerByCFIFrameInfo(const vector<StackFrame*> &frames,
- CFIFrameInfo *cfi_frame_info);
+ StackFrameX86* GetCallerByCFIFrameInfo(const vector<StackFrame*> &frames,
+ CFIFrameInfo* cfi_frame_info);
// Assuming a traditional frame layout --- where the caller's %ebp
// has been pushed just after the return address and the callee's
// %ebp points to the saved %ebp --- construct the frame that called
// frames.back(). The caller takes ownership of the returned frame.
// Return NULL on failure.
- StackFrameX86 *GetCallerByEBPAtBase(const vector<StackFrame*> &frames);
+ StackFrameX86* GetCallerByEBPAtBase(const vector<StackFrame*> &frames);
// Stores the CPU context corresponding to the innermost stack frame to
// be returned by GetContextFrame.
- const MDRawContextX86 *context_;
+ const MDRawContextX86* context_;
// Our register map, for cfi_walker_.
static const CFIWalker::RegisterSet cfi_register_map_[];
diff --git a/src/processor/stackwalker_x86_unittest.cc b/src/processor/stackwalker_x86_unittest.cc
index 08e2a6eb..23efe87d 100644
--- a/src/processor/stackwalker_x86_unittest.cc
+++ b/src/processor/stackwalker_x86_unittest.cc
@@ -48,6 +48,7 @@
using google_breakpad::BasicSourceLineResolver;
using google_breakpad::CallStack;
+using google_breakpad::StackFrameSymbolizer;
using google_breakpad::StackFrame;
using google_breakpad::StackFrameX86;
using google_breakpad::StackwalkerX86;
@@ -148,8 +149,9 @@ TEST_F(SanityCheck, NoResolver) {
raw_context.eip = 0x40000200;
raw_context.ebp = 0x80000000;
+ StackFrameSymbolizer frame_symbolizer(NULL, NULL);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- NULL, NULL);
+ &frame_symbolizer);
// This should succeed, even without a resolver or supplier.
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
@@ -168,8 +170,9 @@ TEST_F(GetContextFrame, Simple) {
raw_context.eip = 0x40000200;
raw_context.ebp = 0x80000000;
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
@@ -200,8 +203,9 @@ TEST_F(GetCallerFrame, Traditional) {
raw_context.esp = stack_section.start().Value();
raw_context.ebp = frame0_ebp.Value();
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
@@ -255,8 +259,9 @@ TEST_F(GetCallerFrame, TraditionalScan) {
// for something that looks like a return address.
raw_context.ebp = 0xd43eed6e;
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
@@ -316,8 +321,9 @@ TEST_F(GetCallerFrame, TraditionalScanLongWay) {
// for something that looks like a return address.
raw_context.ebp = 0xd43eed6e;
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
@@ -387,8 +393,9 @@ TEST_F(GetCallerFrame, WindowsFrameData) {
raw_context.esp = stack_section.start().Value();
raw_context.ebp = 0xf052c1de; // should not be needed to walk frame
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
@@ -458,8 +465,9 @@ TEST_F(GetCallerFrame, WindowsFrameDataAligned) {
raw_context.esp = stack_section.start().Value();
raw_context.ebp = 0xf052c1de; // should not be needed to walk frame
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
@@ -540,8 +548,9 @@ TEST_F(GetCallerFrame, WindowsFrameDataParameterSize) {
raw_context.esp = stack_section.start().Value();
raw_context.ebp = frame0_ebp.Value();
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(3U, frames->size());
@@ -634,8 +643,9 @@ TEST_F(GetCallerFrame, WindowsFrameDataScan) {
raw_context.esp = stack_section.start().Value();
raw_context.ebp = 0x2ae314cd; // should not be needed to walk frame
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
@@ -717,8 +727,9 @@ TEST_F(GetCallerFrame, WindowsFrameDataBadEIPScan) {
raw_context.esp = stack_section.start().Value();
raw_context.ebp = frame0_ebp.Value();
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
@@ -784,8 +795,9 @@ TEST_F(GetCallerFrame, WindowsFPOUnchangedEBP) {
// Frame pointer unchanged from caller.
raw_context.ebp = frame1_ebp.Value();
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
@@ -860,8 +872,9 @@ TEST_F(GetCallerFrame, WindowsFPOUsedEBP) {
// RaisedByTheAliens uses %ebp for its own mysterious purposes.
raw_context.ebp = 0xecbdd1a5;
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
@@ -997,8 +1010,9 @@ TEST_F(GetCallerFrame, WindowsFPOSystemCall) {
ASSERT_TRUE(raw_context.esp == frame0_esp.Value());
raw_context.ebp = frame1_ebp.Value();
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
@@ -1097,8 +1111,9 @@ struct CFIFixture: public StackwalkerX86Fixture {
RegionFromSection();
raw_context.esp = stack_section.start().Value();
+ StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
- &supplier, &resolver);
+ &frame_symbolizer);
ASSERT_TRUE(walker.Walk(&call_stack));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());