fix(esp_system/panic): ensure breakpoint set from panic handler gets hit afterwards

This commit is contained in:
Samuel Obuch
2026-09-10 10:38:51 +08:00
committed by BOT
parent 93ba4e6fd5
commit 3f4b304719
4 changed files with 36 additions and 6 deletions
+13 -1
View File
@@ -364,6 +364,12 @@ void esp_panic_handler(panic_info_t *info)
}
panic_print_str("Setting breakpoint at 0x");
panic_print_hex((uint32_t)info->addr);
#if __riscv
// Interrupts can trigger before the breakpoint is hit,
// so disable them on global level to avoid any further execution.
RV_CLEAR_CSR(mstatus, MSTATUS_MPIE | MSTATUS_SPIE | MSTATUS_UPIE);
panic_print_str(", disabling global interrupts,");
#endif
panic_print_str(" and returning...\r\n");
#if CONFIG_APPTRACE_ENABLE
#if CONFIG_APPTRACE_SV_ENABLE
@@ -375,7 +381,13 @@ void esp_panic_handler(panic_info_t *info)
#endif
disable_all_wdts();
esp_cpu_set_breakpoint(0, info->addr); // use breakpoint 0
// use breakpoint 0
if (esp_cpu_set_breakpoint(0, info->addr) != ESP_OK) {
#if __riscv
// Halt here if unable to set a breakpoint.
asm("ebreak");
#endif
}
return;
}
#endif //CONFIG_ESP_DEBUG_OCDAWARE
@@ -314,6 +314,8 @@ void panic_soc_fill_info(void *f, panic_info_t *info)
info->details = print_cache_err_details;
}
}
info->addr = (void *)frame->pc;
}
uint32_t panic_get_address(const void *f)
@@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "freertos/xtensa_rtos.h"
#include "esp_private/panic_reason.h"
#include "soc/soc.h"
@@ -58,4 +63,15 @@ _xt_panic:
mov a6,sp
call4 panicHandler
ret
/* When panicHandler returns, resume at the crashing PC so the breakpoint is hit there.
* Restore the interrupted GPRs/SP from the frame (EXCSAVE_1/EPC_1 may have
* been clobbered by windowed C calls). Do not restore PS: it was sampled at
* the panic interrupt level, and restoring DEBUGLEVEL would mask IBREAK.
*/
call0 _xt_context_restore
l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */
wsr a0, EPC_1
l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */
l32i sp, sp, XT_STK_A1 /* remove exception frame */
rsync /* ensure EPC written */
rfe /* PS.EXCM is cleared */