diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp --- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -708,12 +708,49 @@ case llvm::Triple::aarch64_32: case llvm::Triple::aarch64: { + // xnu describes three things with type EXC_BREAKPOINT: + // + // exc_code 0x102 [EXC_ARM_DA_DEBUG], exc_sub_code addr-of-insn + // Watchpoint access. exc_sub_code is the address of the + // instruction which trigged the watchpoint trap. + // debugserver may add the watchpoint number that was triggered + // in exc_sub_sub_code. + // + // exc_code 1 [EXC_ARM_BREAKPOINT], exc_sub_code 0 + // Instruction step has completed. + // + // exc_code 1 [EXC_ARM_BREAKPOINT], exc_sub_code address-of-instruction + // Software breakpoint instruction executed. + if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT { // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0 // is set - is_actual_breakpoint = false; + is_actual_breakpoint = true; is_trace_if_actual_breakpoint_missing = true; +#ifndef NDEBUG + if (thread.GetTemporaryResumeState() != eStateStepping) { + StreamString s; + s.Printf("CreateStopReasonWithMachException got EXC_BREAKPOINT [1,0] " + "indicating trace event, but thread is not tracing, it has " + "ResumeState %d", + thread.GetTemporaryResumeState()); + if (RegisterContextSP regctx = thread.GetRegisterContext()) { + if (const RegisterInfo *ri = regctx->GetRegisterInfoByName("esr")) { + uint32_t esr = + (uint32_t)regctx->ReadRegisterAsUnsigned(ri, UINT32_MAX); + if (esr != UINT32_MAX) { + s.Printf(" esr value: 0x%" PRIx32, esr); + } + } + } + llvm::report_fatal_error(s.GetData()); + lldbassert( + false && + "CreateStopReasonWithMachException got EXC_BREAKPOINT [1,0] " + "indicating trace event, but thread was not doing a step."); + } +#endif } if (exc_code == 0x102) // EXC_ARM_DA_DEBUG {