From 3a96d07e11beed6126df1803e577214794018e49 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 29 Jul 2020 12:20:52 +0200 Subject: [PATCH] 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. --- components/esp32/panic.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/components/esp32/panic.c b/components/esp32/panic.c index f92d093bb0..ba3ed2b6d4 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -362,7 +362,7 @@ void xt_unhandled_exception(XtExcFrame *frame) return; } panicPutStr(". Exception was unhandled.\r\n"); - if (exccause == 0 /* IllegalInstruction */) { + if (exccause == EXCCAUSE_ILLEGAL) { illegal_instruction_helper(frame); } 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); //Check if first frame is valid - bool corrupted = (esp_stack_ptr_is_sane(stk_frame.sp) && - esp_ptr_executable((void*)esp_cpu_process_stack_pc(stk_frame.pc))) ? - false : true; + bool corrupted = !(esp_stack_ptr_is_sane(stk_frame.sp) && + (esp_ptr_executable((void *)esp_cpu_process_stack_pc(stk_frame.pc)) || + /* 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 while (i-- > 0 && stk_frame.next_pc != 0 && !corrupted) { if (!esp_backtrace_get_next_frame(&stk_frame)) { //Get next stack frame