mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-03 12:44:33 +02:00
panic: skip over the first invalid PC in case of InstrFetchProhibited
InstrFetchProhibited usually occurs because of a jump to an invalid pointer. In this case, PC in the exception frame is the address of the jump destination. 'esp_ptr_executable' check in print_backtrace function recognizes the first frame as invalid, and the backtrace is interrupted. This prevents the user from finding the location where the invalid pointer is dereferenced. Bypass the 'esp_ptr_executable' check if the exception cause is InstrFetchProhibited. Update the test case to no longer ignore this issue.
This commit is contained in:
@@ -156,7 +156,9 @@ static void print_backtrace(const void *f, int core)
|
|||||||
|
|
||||||
//Check if first frame is valid
|
//Check if first frame is valid
|
||||||
bool corrupted = !(esp_stack_ptr_is_sane(stk_frame.sp) &&
|
bool corrupted = !(esp_stack_ptr_is_sane(stk_frame.sp) &&
|
||||||
esp_ptr_executable((void *)esp_cpu_process_stack_pc(stk_frame.pc)));
|
(esp_ptr_executable((void *)esp_cpu_process_stack_pc(stk_frame.pc)) ||
|
||||||
|
/* Ignore the first corrupted PC in case of InstrFetchProhibited */
|
||||||
|
frame->exccause == EXCCAUSE_INSTR_PROHIBITED));
|
||||||
|
|
||||||
uint32_t i = ((depth <= 0) ? INT32_MAX : depth) - 1; //Account for stack frame that's already printed
|
uint32_t i = ((depth <= 0) ? INT32_MAX : depth) - 1; //Account for stack frame that's already printed
|
||||||
while (i-- > 0 && stk_frame.next_pc != 0 && !corrupted) {
|
while (i-- > 0 && stk_frame.next_pc != 0 && !corrupted) {
|
||||||
@@ -456,7 +458,7 @@ static void frame_to_panic_info(XtExcFrame *frame, panic_info_t *info, bool pseu
|
|||||||
|
|
||||||
info->description = "Exception was unhandled.";
|
info->description = "Exception was unhandled.";
|
||||||
|
|
||||||
if (info->reason == reason[0]) {
|
if (frame->exccause == EXCCAUSE_ILLEGAL) {
|
||||||
info->details = print_illegal_instruction_details;
|
info->details = print_illegal_instruction_details;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -107,10 +107,7 @@ def instr_fetch_prohibited_inner(env, test_name):
|
|||||||
with get_dut(env, test_name, "test_instr_fetch_prohibited") as dut:
|
with get_dut(env, test_name, "test_instr_fetch_prohibited") as dut:
|
||||||
dut.expect_gme("InstrFetchProhibited")
|
dut.expect_gme("InstrFetchProhibited")
|
||||||
dut.expect_reg_dump(0)
|
dut.expect_reg_dump(0)
|
||||||
dut.expect("Backtrace:")
|
dut.expect_backtrace()
|
||||||
# At the moment the backtrace is corrupted, need to jump over the first PC in case of InstrFetchProhibited.
|
|
||||||
# Fix this and change expect to expect_none.
|
|
||||||
dut.expect("CORRUPTED")
|
|
||||||
dut.expect_elf_sha256()
|
dut.expect_elf_sha256()
|
||||||
dut.expect_none("Guru Meditation")
|
dut.expect_none("CORRUPTED", "Guru Meditation")
|
||||||
test_common(dut, test_name)
|
test_common(dut, test_name)
|
||||||
|
@@ -76,6 +76,10 @@ class PanicTestMixin(object):
|
|||||||
elf_sha256_len = int(sdkconfig.get("CONFIG_APP_RETRIEVE_LEN_ELF_SHA", "16"))
|
elf_sha256_len = int(sdkconfig.get("CONFIG_APP_RETRIEVE_LEN_ELF_SHA", "16"))
|
||||||
self.expect("ELF file SHA256: " + elf_sha256[0:elf_sha256_len])
|
self.expect("ELF file SHA256: " + elf_sha256[0:elf_sha256_len])
|
||||||
|
|
||||||
|
def expect_backtrace(self):
|
||||||
|
self.expect("Backtrace:")
|
||||||
|
self.expect_none("CORRUPTED")
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self._raw_data = None
|
self._raw_data = None
|
||||||
return self
|
return self
|
||||||
|
Reference in New Issue
Block a user