mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 03:07:21 +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:
@ -362,7 +362,7 @@ void xt_unhandled_exception(XtExcFrame *frame)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
panicPutStr(". Exception was unhandled.\r\n");
|
panicPutStr(". Exception was unhandled.\r\n");
|
||||||
if (exccause == 0 /* IllegalInstruction */) {
|
if (exccause == EXCCAUSE_ILLEGAL) {
|
||||||
illegal_instruction_helper(frame);
|
illegal_instruction_helper(frame);
|
||||||
}
|
}
|
||||||
esp_reset_reason_set_hint(ESP_RST_PANIC);
|
esp_reset_reason_set_hint(ESP_RST_PANIC);
|
||||||
@ -468,9 +468,10 @@ static void doBacktrace(XtExcFrame *exc_frame, int depth)
|
|||||||
putEntry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
|
putEntry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
|
||||||
|
|
||||||
//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)) ||
|
||||||
false : true;
|
/* Ignore the first corrupted PC in case of InstrFetchProhibited */
|
||||||
|
exc_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) {
|
||||||
if (!esp_backtrace_get_next_frame(&stk_frame)) { //Get next stack frame
|
if (!esp_backtrace_get_next_frame(&stk_frame)) { //Get next stack frame
|
||||||
|
Reference in New Issue
Block a user