Procházet zdrojové kódy

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.
Ivan Grokhotkov před 5 roky
rodič
revize
5ff9cd495e

+ 4 - 2
components/esp_system/port/panic_handler.c

@@ -156,7 +156,9 @@ static void print_backtrace(const void *f, int core)
 
     //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)));
+                       (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
     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.";
 
-        if (info->reason == reason[0]) {
+        if (frame->exccause == EXCCAUSE_ILLEGAL) {
             info->details = print_illegal_instruction_details;
         }
     }

+ 2 - 5
tools/test_apps/system/panic/panic_tests.py

@@ -107,10 +107,7 @@ def instr_fetch_prohibited_inner(env, test_name):
     with get_dut(env, test_name, "test_instr_fetch_prohibited") as dut:
         dut.expect_gme("InstrFetchProhibited")
         dut.expect_reg_dump(0)
-        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_backtrace()
         dut.expect_elf_sha256()
-        dut.expect_none("Guru Meditation")
+        dut.expect_none("CORRUPTED", "Guru Meditation")
         test_common(dut, test_name)

+ 4 - 0
tools/test_apps/system/panic/test_panic_util/test_panic_util.py

@@ -76,6 +76,10 @@ class PanicTestMixin(object):
         elf_sha256_len = int(sdkconfig.get("CONFIG_APP_RETRIEVE_LEN_ELF_SHA", "16"))
         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):
         self._raw_data = None
         return self