diff options
Diffstat (limited to 'src/google_breakpad/processor')
-rw-r--r-- | src/google_breakpad/processor/stack_frame.h | 30 | ||||
-rw-r--r-- | src/google_breakpad/processor/stack_frame_cpu.h | 6 |
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. |