1diff --git a/src/processor/stackwalker_arm64.cc b/src/processor/stackwalker_arm64.cc
2--- a/src/processor/stackwalker_arm64.cc
3+++ b/src/processor/stackwalker_arm64.cc
4@@ -282,16 +282,27 @@ void StackwalkerARM64::CorrectRegLRByFra
5                  << std::hex << (last_last_fp + 8);
6     return;
7   }
8   last_lr = PtrauthStrip(last_lr);
9
10   last_frame->context.iregs[MD_CONTEXT_ARM64_REG_LR] = last_lr;
11 }
12
13+bool StackwalkerARM64::ValidInstructionPointerInFrame(const StackFrameARM64& frame) {
14+  const uint64_t ip = frame.context.iregs[MD_CONTEXT_ARM64_REG_PC];
15+
16+  if ((ip < 0x1000) || (ip > 0x000fffffffffffff)) {
17+    // The IP points into the first page or above the user space threshold
18+    return false;
19+  }
20+
21+  return true;
22+}
23+
24 StackFrame* StackwalkerARM64::GetCallerFrame(const CallStack* stack,
25                                              bool stack_scan_allowed) {
26   if (!memory_ || !stack) {
27     BPLOG(ERROR) << "Can't get caller frame without memory or stack";
28     return NULL;
29   }
30
31   const vector<StackFrame*> &frames = *stack->frames();
32@@ -300,21 +311,22 @@ StackFrame* StackwalkerARM64::GetCallerF
33
34   // See if there is DWARF call frame information covering this address.
35   scoped_ptr<CFIFrameInfo> cfi_frame_info(
36       frame_symbolizer_->FindCFIFrameInfo(last_frame));
37   if (cfi_frame_info.get())
38     frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get()));
39
40   // If CFI failed, or there wasn't CFI available, fall back to frame pointer.
41-  if (!frame.get())
42+  if (!frame.get() || !ValidInstructionPointerInFrame(*frame))
43     frame.reset(GetCallerByFramePointer(frames));
44
45   // If everything failed, fall back to stack scanning.
46-  if (stack_scan_allowed && !frame.get())
47+  if (stack_scan_allowed &&
48+      (!frame.get() || !ValidInstructionPointerInFrame(*frame)))
49     frame.reset(GetCallerByStackScan(frames));
50
51   // If nothing worked, tell the caller.
52   if (!frame.get())
53     return NULL;
54
55   // Should we terminate the stack walk? (end-of-stack or broken invariant)
56   if (TerminateWalk(frame->context.iregs[MD_CONTEXT_ARM64_REG_PC],
57diff --git a/src/processor/stackwalker_arm64.h b/src/processor/stackwalker_arm64.h
58--- a/src/processor/stackwalker_arm64.h
59+++ b/src/processor/stackwalker_arm64.h
60@@ -92,16 +92,19 @@ class StackwalkerARM64 : public Stackwal
61
62   // GetCallerByFramePointer() depends on the previous frame having recovered
63   // x30($LR) which may not have been done when using CFI.
64   // This function recovers $LR in the previous frame by using the frame-pointer
65   // two frames back to read it from the stack.
66   void CorrectRegLRByFramePointer(const vector<StackFrame*>& frames,
67                                   StackFrameARM64* last_frame);
68
69+  // Return true if the instruction pointer points into the first 4KiB of memory
70+  bool ValidInstructionPointerInFrame(const StackFrameARM64& frame);
71+
72   // Stores the CPU context corresponding to the youngest stack frame, to
73   // be returned by GetContextFrame.
74   const MDRawContextARM64* context_;
75
76   // Validity mask for youngest stack frame. This is always
77   // CONTEXT_VALID_ALL in real use; it is only changeable for the sake of
78   // unit tests.
79   uint64_t context_frame_validity_;
80