aboutsummaryrefslogtreecommitdiff
path: root/src/google_breakpad/processor
diff options
context:
space:
mode:
authorjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-01-22 22:38:41 +0000
committerjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-01-22 22:38:41 +0000
commitbe81ededf84628cca376bd79d7fb097f42da2709 (patch)
tree568c297b900469034f55590f058d8daec9229167 /src/google_breakpad/processor
parentFix remaining processor/scoped_ptr.h references for reals. (diff)
downloadbreakpad-be81ededf84628cca376bd79d7fb097f42da2709.tar.xz
Print the correct return address, even on architectures where StackFrame::instruction is offset.
a=bruce.dawson, r=jimblandy git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1105 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/google_breakpad/processor')
-rw-r--r--src/google_breakpad/processor/stack_frame.h30
-rw-r--r--src/google_breakpad/processor/stack_frame_cpu.h6
2 files changed, 31 insertions, 5 deletions
diff --git a/src/google_breakpad/processor/stack_frame.h b/src/google_breakpad/processor/stack_frame.h
index 2f31e5c1..e8803804 100644
--- a/src/google_breakpad/processor/stack_frame.h
+++ b/src/google_breakpad/processor/stack_frame.h
@@ -83,11 +83,31 @@ struct StackFrame {
}
};
- // 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
- // the instruction that caused execution to branch to a called function,
- // but may not necessarily point to the exact beginning of that instruction.
+ // Return the actual return address, as saved on the stack or in a
+ // register. See the comments for 'instruction', below, for details.
+ virtual u_int64_t ReturnAddress() const { return instruction; }
+
+ // 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 address is within the instruction that
+ // caused execution to branch to this frame's callee (although it may
+ // not point to the exact beginning of that instruction). This ensures
+ // that, when we look up the source code location for this frame, we
+ // get the source location of the call, not of the point at which
+ // control will resume when the call returns, which may be on the next
+ // line. (If the compiler knows the callee never returns, it may even
+ // place the call instruction at the very end of the caller's machine
+ // code, such that the "return address" (which will never be used)
+ // immediately after the call instruction is in an entirely different
+ // function, perhaps even from a different source file.)
+ //
+ // On some architectures, the return address as saved on the stack or in
+ // a register is fine for looking up the point of the call. On others, it
+ // requires adjustment. ReturnAddress returns the address as saved by the
+ // machine.
u_int64_t instruction;
// The module in which the instruction resides.
diff --git a/src/google_breakpad/processor/stack_frame_cpu.h b/src/google_breakpad/processor/stack_frame_cpu.h
index 90328760..34171f37 100644
--- a/src/google_breakpad/processor/stack_frame_cpu.h
+++ b/src/google_breakpad/processor/stack_frame_cpu.h
@@ -77,6 +77,9 @@ struct StackFrameX86 : public StackFrame {
cfi_frame_info(NULL) {}
~StackFrameX86();
+ // Overriden to return the return address as saved on the stack.
+ virtual u_int64_t ReturnAddress() const;
+
// Register state. This is only fully valid for the topmost frame in a
// stack. In other frames, the values of nonvolatile registers may be
// present, given sufficient debugging information. Refer to
@@ -147,6 +150,9 @@ struct StackFrameAMD64 : public StackFrame {
StackFrameAMD64() : context(), context_validity(CONTEXT_VALID_NONE) {}
+ // Overriden to return the return address as saved on the stack.
+ virtual u_int64_t ReturnAddress() const;
+
// Register state. This is only fully valid for the topmost frame in a
// stack. In other frames, which registers are present depends on what
// debugging information we had available. Refer to context_validity.