aboutsummaryrefslogtreecommitdiff
path: root/src/processor/stackwalker_arm64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/processor/stackwalker_arm64.cc')
-rw-r--r--src/processor/stackwalker_arm64.cc15
1 files changed, 6 insertions, 9 deletions
diff --git a/src/processor/stackwalker_arm64.cc b/src/processor/stackwalker_arm64.cc
index 31119a97..f9660112 100644
--- a/src/processor/stackwalker_arm64.cc
+++ b/src/processor/stackwalker_arm64.cc
@@ -252,16 +252,13 @@ StackFrame* StackwalkerARM64::GetCallerFrame(const CallStack* stack,
if (!frame.get())
return NULL;
- // An instruction address of zero marks the end of the stack.
- if (frame->context.iregs[MD_CONTEXT_ARM64_REG_PC] == 0)
- return NULL;
-
- // If the new stack pointer is at a lower address than the old, then
- // that's clearly incorrect. Treat this as end-of-stack to enforce
- // progress and avoid infinite loops.
- if (frame->context.iregs[MD_CONTEXT_ARM64_REG_SP]
- < last_frame->context.iregs[MD_CONTEXT_ARM64_REG_SP])
+ // Should we terminate the stack walk? (end-of-stack or broken invariant)
+ if (TerminateWalk(frame->context.iregs[MD_CONTEXT_ARM64_REG_PC],
+ frame->context.iregs[MD_CONTEXT_ARM64_REG_SP],
+ last_frame->context.iregs[MD_CONTEXT_ARM64_REG_SP],
+ frames.size() == 1)) {
return NULL;
+ }
// The new frame's context's PC is the return address, which is one
// instruction past the instruction that caused us to arrive at the callee.