aboutsummaryrefslogtreecommitdiff
path: root/src/google_breakpad
diff options
context:
space:
mode:
authorted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-10-01 13:01:57 +0000
committerted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-10-01 13:01:57 +0000
commit8c33b3e9c95a67a9bb06c033d5d4c28d9a55168b (patch)
treeef075e1413f52c73ce23e3a967d4cfa1311745e1 /src/google_breakpad
parentFix a segmentation fault bug in MinidumpAssertion::Read(). (diff)
downloadbreakpad-8c33b3e9c95a67a9bb06c033d5d4c28d9a55168b.tar.xz
Refactor some bits of StackWalkerX86 / StackFrameX86 out into their respective parent classes so they can be used by other architecture implementations.
R=jimb at http://breakpad.appspot.com/205001/show git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@703 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/google_breakpad')
-rw-r--r--src/google_breakpad/processor/stack_frame.h39
-rw-r--r--src/google_breakpad/processor/stack_frame_cpu.h18
-rw-r--r--src/google_breakpad/processor/stackwalker.h37
3 files changed, 73 insertions, 21 deletions
diff --git a/src/google_breakpad/processor/stack_frame.h b/src/google_breakpad/processor/stack_frame.h
index b330f8ae..a47c621f 100644
--- a/src/google_breakpad/processor/stack_frame.h
+++ b/src/google_breakpad/processor/stack_frame.h
@@ -40,6 +40,19 @@ class CodeModule;
using std::string;
struct StackFrame {
+ // Indicates how well the instruction pointer derived during
+ // stack walking is trusted. Since the stack walker can resort to
+ // stack scanning, it can wind up with dubious frames.
+ // In rough order of "trust metric".
+ enum FrameTrust {
+ FRAME_TRUST_NONE, // Unknown
+ FRAME_TRUST_SCAN, // Scanned the stack, found this
+ FRAME_TRUST_CFI_SCAN, // Scanned the stack using call frame info, found this
+ FRAME_TRUST_FP, // Derived from frame pointer
+ FRAME_TRUST_CFI, // Derived from call frame info
+ FRAME_TRUST_CONTEXT // Given as instruction pointer in a context
+ };
+
StackFrame()
: instruction(),
module(NULL),
@@ -47,9 +60,29 @@ struct StackFrame {
function_base(),
source_file_name(),
source_line(),
- source_line_base() {}
+ source_line_base(),
+ trust(FRAME_TRUST_NONE) {}
virtual ~StackFrame() {}
+ // Return a string describing how this stack frame was found
+ // by the stackwalker.
+ string trust_description() const {
+ switch (trust) {
+ case StackFrame::FRAME_TRUST_NONE:
+ return "unknown";
+ case StackFrame::FRAME_TRUST_CONTEXT:
+ return "given as instruction pointer in context";
+ case StackFrame::FRAME_TRUST_CFI:
+ return "call frame info";
+ case StackFrame::FRAME_TRUST_CFI_SCAN:
+ return "call frame info with scanning";
+ case StackFrame::FRAME_TRUST_FP:
+ return "previous frame's frame pointer";
+ case StackFrame::FRAME_TRUST_SCAN:
+ return "stack scanning";
+ }
+ };
+
// The program counter location as an absolute virtual address. For the
// innermost called frame in a stack, this will be an exact program counter
// or instruction pointer value. For all other frames, this will be within
@@ -77,6 +110,10 @@ struct StackFrame {
// The start address of the source line, may be omitted if debug symbols
// are not available.
u_int64_t source_line_base;
+
+ // Amount of trust the stack walker has in the instruction pointer
+ // of this frame.
+ FrameTrust trust;
};
} // namespace google_breakpad
diff --git a/src/google_breakpad/processor/stack_frame_cpu.h b/src/google_breakpad/processor/stack_frame_cpu.h
index 0996886f..805b6bc3 100644
--- a/src/google_breakpad/processor/stack_frame_cpu.h
+++ b/src/google_breakpad/processor/stack_frame_cpu.h
@@ -70,23 +70,9 @@ struct StackFrameX86 : public StackFrame {
CONTEXT_VALID_ALL = -1
};
- // Indicates how well we trust the instruction pointer we derived
- // during stack walking. Since the stack walker can resort to
- // stack scanning, we can wind up with dubious frames.
- // In rough order of "trust metric".
- enum FrameTrust {
- FRAME_TRUST_NONE, // Unknown
- FRAME_TRUST_SCAN, // Scanned the stack, found this
- FRAME_TRUST_CFI_SCAN, // Scanned the stack using call frame info, found this
- FRAME_TRUST_FP, // Derived from frame pointer
- FRAME_TRUST_CFI, // Derived from call frame info
- FRAME_TRUST_CONTEXT // Given as instruction pointer in a context
- };
-
StackFrameX86()
: context(),
context_validity(CONTEXT_VALID_NONE),
- trust(FRAME_TRUST_NONE),
windows_frame_info(NULL),
cfi_frame_info(NULL) {}
~StackFrameX86();
@@ -101,10 +87,6 @@ struct StackFrameX86 : public StackFrame {
// the OR operator doesn't work well with enumerated types. This indicates
// which fields in context are valid.
int context_validity;
-
- // Amount of trust the stack walker has in the instruction pointer
- // of this frame.
- FrameTrust trust;
// Any stack walking information we found describing this.instruction.
// These may be NULL if there is no such information for that address.
diff --git a/src/google_breakpad/processor/stackwalker.h b/src/google_breakpad/processor/stackwalker.h
index 36d721d1..8dd2a971 100644
--- a/src/google_breakpad/processor/stackwalker.h
+++ b/src/google_breakpad/processor/stackwalker.h
@@ -44,12 +44,12 @@
#include <set>
#include <string>
#include "google_breakpad/common/breakpad_types.h"
+#include "google_breakpad/processor/code_modules.h"
+#include "google_breakpad/processor/memory_region.h"
namespace google_breakpad {
class CallStack;
-class CodeModules;
-class MemoryRegion;
class MinidumpContext;
class SourceLineResolverInterface;
struct StackFrame;
@@ -108,6 +108,39 @@ class Stackwalker {
// Returns false otherwise.
bool InstructionAddressSeemsValid(u_int64_t address);
+ // Scan the stack starting at location_start, looking for an address
+ // that looks like a valid instruction pointer. Addresses must
+ // 1) be contained in the current stack memory
+ // 2) pass the checks in InstructionAddressSeemsValid
+ //
+ // Returns true if a valid-looking instruction pointer was found.
+ // When returning true, sets location_found to the address at which
+ // the value was found, and ip_found to the value contained at that
+ // location in memory.
+ template<typename InstructionType>
+ bool ScanForReturnAddress(InstructionType location_start,
+ InstructionType *location_found,
+ InstructionType *ip_found) {
+ const int kRASearchWords = 15;
+ for (InstructionType location = location_start;
+ location <= location_start + kRASearchWords * sizeof(InstructionType);
+ location += sizeof(InstructionType)) {
+ InstructionType ip;
+ if (!memory_->GetMemoryAtAddress(location, &ip))
+ break;
+
+ if (modules_ && modules_->GetModuleForAddress(ip) &&
+ InstructionAddressSeemsValid(ip)) {
+
+ *ip_found = ip;
+ *location_found = location;
+ return true;
+ }
+ }
+ // nothing found
+ return false;
+ }
+
// Information about the system that produced the minidump. Subclasses
// and the SymbolSupplier may find this information useful.
const SystemInfo *system_info_;