aboutsummaryrefslogtreecommitdiff
path: root/src/processor/stackwalker_ppc64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/processor/stackwalker_ppc64.cc')
-rw-r--r--src/processor/stackwalker_ppc64.cc13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/processor/stackwalker_ppc64.cc b/src/processor/stackwalker_ppc64.cc
index 51c71fe5..fb2bac3c 100644
--- a/src/processor/stackwalker_ppc64.cc
+++ b/src/processor/stackwalker_ppc64.cc
@@ -32,6 +32,7 @@
// See stackwalker_ppc64.h for documentation.
+#include "common/scoped_ptr.h"
#include "processor/stackwalker_ppc64.h"
#include "google_breakpad/processor/call_stack.h"
#include "google_breakpad/processor/memory_region.h"
@@ -112,7 +113,7 @@ StackFrame* StackwalkerPPC64::GetCallerFrame(const CallStack* stack,
return NULL;
}
- StackFramePPC64* frame = new StackFramePPC64();
+ scoped_ptr<StackFramePPC64> frame(new StackFramePPC64());
frame->context = last_frame->context;
frame->context.srr0 = instruction;
@@ -121,6 +122,14 @@ StackFrame* StackwalkerPPC64::GetCallerFrame(const CallStack* stack,
StackFramePPC64::CONTEXT_VALID_GPR1;
frame->trust = StackFrame::FRAME_TRUST_FP;
+ // Should we terminate the stack walk? (end-of-stack or broken invariant)
+ if (TerminateWalk(instruction,
+ stack_pointer,
+ last_frame->context.gpr[1],
+ stack->frames()->size() == 1)) {
+ return NULL;
+ }
+
// frame->context.srr0 is the return address, which is one instruction
// past the branch that caused us to arrive at the callee. Set
// frame_ppc64->instruction to eight less than that. Since all ppc64
@@ -130,7 +139,7 @@ StackFrame* StackwalkerPPC64::GetCallerFrame(const CallStack* stack,
// return address value may access the context.srr0 field of StackFramePPC64.
frame->instruction = frame->context.srr0 - 8;
- return frame;
+ return frame.release();
}