Skip to content

Commit 7acda7b

Browse files
committed
Merge branch 'bugfix/panic_instr_fetch_prohibited' into 'master'
panic: don't interrupt the backtrace for InstrFetchProhibited exceptions See merge request espressif/esp-idf!9851
2 parents 64f2ac4 + 4e7e859 commit 7acda7b

File tree

6 files changed

+48
-33
lines changed

6 files changed

+48
-33
lines changed

components/esp_system/port/panic_handler.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,9 @@ static void print_backtrace(const void *f, int core)
156156

157157
//Check if first frame is valid
158158
bool corrupted = !(esp_stack_ptr_is_sane(stk_frame.sp) &&
159-
esp_ptr_executable((void *)esp_cpu_process_stack_pc(stk_frame.pc)));
159+
(esp_ptr_executable((void *)esp_cpu_process_stack_pc(stk_frame.pc)) ||
160+
/* Ignore the first corrupted PC in case of InstrFetchProhibited */
161+
frame->exccause == EXCCAUSE_INSTR_PROHIBITED));
160162

161163
uint32_t i = ((depth <= 0) ? INT32_MAX : depth) - 1; //Account for stack frame that's already printed
162164
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
456458

457459
info->description = "Exception was unhandled.";
458460

459-
if (info->reason == reason[0]) {
461+
if (frame->exccause == EXCCAUSE_ILLEGAL) {
460462
info->details = print_illegal_instruction_details;
461463
}
462464
}

components/freertos/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ menu "FreeRTOS"
174174

175175
config FREERTOS_ISR_STACKSIZE
176176
int "ISR stack size"
177-
range 2100 32768 if ESP32_COREDUMP_DATA_FORMAT_ELF
178-
default 2100 if ESP32_COREDUMP_DATA_FORMAT_ELF
177+
range 2096 32768 if ESP32_COREDUMP_DATA_FORMAT_ELF
178+
default 2096 if ESP32_COREDUMP_DATA_FORMAT_ELF
179179
range 1536 32768
180180
default 1536
181181
help

components/freertos/xtensa/include/freertos/FreeRTOSConfig.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,16 @@ int xt_clock_freq(void) __attribute__((deprecated));
196196
#define configIDLE_TASK_STACK_SIZE CONFIG_FREERTOS_IDLE_TASK_STACKSIZE
197197
#endif
198198

199-
/* The Xtensa port uses a separate interrupt stack. Adjust the stack size */
200-
/* to suit the needs of your specific application. */
199+
/* Stack alignment, architecture specifc. Must be a power of two. */
200+
#define configSTACK_ALIGNMENT 16
201+
202+
/* The Xtensa port uses a separate interrupt stack. Adjust the stack size
203+
* to suit the needs of your specific application.
204+
* Size needs to be aligned to the stack increment, since the location of
205+
* the stack for the 2nd CPU will be calculated using configISR_STACK_SIZE.
206+
*/
201207
#ifndef configISR_STACK_SIZE
202-
#define configISR_STACK_SIZE CONFIG_FREERTOS_ISR_STACKSIZE
208+
#define configISR_STACK_SIZE ((CONFIG_FREERTOS_ISR_STACKSIZE + configSTACK_ALIGNMENT - 1) & (~(configSTACK_ALIGNMENT - 1)))
203209
#endif
204210

205211
/* Minimal heap size to make sure examples can run on memory limited

tools/test_apps/system/panic/app_test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env python
2+
import sys
23
import panic_tests as test
34
from test_panic_util.test_panic_util import panic_test, run_all
45

@@ -247,4 +248,4 @@ def test_coredump_abort_flash_bin_crc(env, extra_data):
247248

248249

249250
if __name__ == '__main__':
250-
run_all(__file__)
251+
run_all(__file__, sys.argv[1:])

tools/test_apps/system/panic/panic_tests.py

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,22 @@ def task_wdt_inner(env, test_name):
1919
dut.expect("CPU 0: main")
2020
dut.expect(re.compile(r"abort\(\) was called at PC [0-9xa-f]+ on core 0"))
2121
dut.expect_none("register dump:")
22-
dut.expect("Backtrace:")
22+
dut.expect_backtrace()
2323
dut.expect_elf_sha256()
24-
dut.expect_none("CORRUPTED", "Guru Meditation")
24+
dut.expect_none("Guru Meditation")
2525
test_common(dut, test_name)
2626

2727

2828
def int_wdt_inner(env, test_name):
2929
with get_dut(env, test_name, "test_int_wdt", qemu_wdt_enable=True) as dut:
3030
dut.expect_gme("Interrupt wdt timeout on CPU0")
3131
dut.expect_reg_dump(0)
32-
dut.expect("Backtrace:")
33-
dut.expect_none("CORRUPTED", "Guru Meditation")
32+
dut.expect_backtrace()
33+
dut.expect_none("Guru Meditation")
3434
dut.expect_reg_dump(1)
35-
dut.expect("Backtrace:")
35+
dut.expect_backtrace()
3636
dut.expect_elf_sha256()
37-
dut.expect_none("CORRUPTED", "Guru Meditation")
37+
dut.expect_none("Guru Meditation")
3838
test_common(dut, test_name)
3939

4040

@@ -44,11 +44,11 @@ def int_wdt_cache_disabled_inner(env, test_name):
4444
dut.expect_gme("Interrupt wdt timeout on CPU0")
4545
dut.expect_reg_dump(0)
4646
dut.expect("Backtrace:")
47-
dut.expect_none("CORRUPTED", "Guru Meditation")
47+
dut.expect_none("Guru Meditation")
4848
dut.expect_reg_dump(1)
49-
dut.expect("Backtrace:")
49+
dut.expect_backtrace()
5050
dut.expect_elf_sha256()
51-
dut.expect_none("CORRUPTED", "Guru Meditation")
51+
dut.expect_none("Guru Meditation")
5252
test_common(dut, test_name)
5353

5454

@@ -57,28 +57,28 @@ def cache_error_inner(env, test_name):
5757
dut.expect("Re-enable cpu cache.")
5858
dut.expect_gme("Cache disabled but cached memory region accessed")
5959
dut.expect_reg_dump(0)
60-
dut.expect("Backtrace:")
60+
dut.expect_backtrace()
6161
dut.expect_elf_sha256()
62-
dut.expect_none("CORRUPTED", "Guru Meditation")
62+
dut.expect_none("Guru Meditation")
6363
test_common(dut, test_name)
6464

6565

6666
def abort_inner(env, test_name):
6767
with get_dut(env, test_name, "test_abort") as dut:
6868
dut.expect(re.compile(r"abort\(\) was called at PC [0-9xa-f]+ on core 0"))
69-
dut.expect("Backtrace:")
69+
dut.expect_backtrace()
7070
dut.expect_elf_sha256()
71-
dut.expect_none("CORRUPTED", "Guru Meditation", "Re-entered core dump")
71+
dut.expect_none("Guru Meditation", "Re-entered core dump")
7272
test_common(dut, test_name)
7373

7474

7575
def storeprohibited_inner(env, test_name):
7676
with get_dut(env, test_name, "test_storeprohibited") as dut:
7777
dut.expect_gme("StoreProhibited")
7878
dut.expect_reg_dump(0)
79-
dut.expect("Backtrace:")
79+
dut.expect_backtrace()
8080
dut.expect_elf_sha256()
81-
dut.expect_none("CORRUPTED", "Guru Meditation")
81+
dut.expect_none("Guru Meditation")
8282
test_common(dut, test_name)
8383

8484

@@ -87,30 +87,27 @@ def stack_overflow_inner(env, test_name):
8787
dut.expect_gme("Unhandled debug exception")
8888
dut.expect("Stack canary watchpoint triggered (main)")
8989
dut.expect_reg_dump(0)
90-
dut.expect("Backtrace:")
90+
dut.expect_backtrace()
9191
dut.expect_elf_sha256()
92-
dut.expect_none("CORRUPTED", "Guru Meditation")
92+
dut.expect_none("Guru Meditation")
9393
test_common(dut, test_name)
9494

9595

9696
def illegal_instruction_inner(env, test_name):
9797
with get_dut(env, test_name, "test_illegal_instruction") as dut:
9898
dut.expect_gme("IllegalInstruction")
9999
dut.expect_reg_dump(0)
100-
dut.expect("Backtrace:")
100+
dut.expect_backtrace()
101101
dut.expect_elf_sha256()
102-
dut.expect_none("CORRUPTED", "Guru Meditation")
102+
dut.expect_none("Guru Meditation")
103103
test_common(dut, test_name)
104104

105105

106106
def instr_fetch_prohibited_inner(env, test_name):
107107
with get_dut(env, test_name, "test_instr_fetch_prohibited") as dut:
108108
dut.expect_gme("InstrFetchProhibited")
109109
dut.expect_reg_dump(0)
110-
dut.expect("Backtrace:")
111-
# At the moment the backtrace is corrupted, need to jump over the first PC in case of InstrFetchProhibited.
112-
# Fix this and change expect to expect_none.
113-
dut.expect("CORRUPTED")
110+
dut.expect_backtrace()
114111
dut.expect_elf_sha256()
115112
dut.expect_none("Guru Meditation")
116113
test_common(dut, test_name)

tools/test_apps/system/panic/test_panic_util/test_panic_util.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ def expect_elf_sha256(self):
7676
elf_sha256_len = int(sdkconfig.get("CONFIG_APP_RETRIEVE_LEN_ELF_SHA", "16"))
7777
self.expect("ELF file SHA256: " + elf_sha256[0:elf_sha256_len])
7878

79+
def expect_backtrace(self):
80+
self.expect("Backtrace:")
81+
self.expect_none("CORRUPTED")
82+
7983
def __enter__(self):
8084
self._raw_data = None
8185
return self
@@ -155,14 +159,19 @@ def get_dut(env, app_config_name, test_name, qemu_wdt_enable=False):
155159
return dut
156160

157161

158-
def run_all(filename):
159-
""" Helper function to run all test cases defined in a file; to be called from __main__. """
162+
def run_all(filename, case_filter=[]):
163+
""" Helper function to run test cases defined in a file; to be called from __main__.
164+
case_filter is an optional list of case names to run.
165+
If not specified, all test cases are run.
166+
"""
160167
TinyFW.set_default_config(env_config_file=None, test_suite_name=TEST_SUITE)
161168
test_methods = SearchCases.Search.search_test_cases(filename)
162169
test_methods = filter(lambda m: not m.case_info["ignore"], test_methods)
163170
test_cases = CaseConfig.Parser.apply_config(test_methods, None)
164171
tests_failed = []
165172
for case in test_cases:
173+
if case_filter and case.test_method.__name__ not in case_filter:
174+
continue
166175
result = case.run()
167176
if not result:
168177
tests_failed.append(case)

0 commit comments

Comments
 (0)