mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 18:10:57 +02:00
test(panic_handler): Added unit test to verify panic handler can halt
This test verifies that the panic handler can indeed halt when configured to print and halt instead of rebboting.
This commit is contained in:
@@ -83,6 +83,10 @@ void test_coredump_summary(void);
|
|||||||
|
|
||||||
void test_panic_print_backtrace(void);
|
void test_panic_print_backtrace(void);
|
||||||
|
|
||||||
|
#if CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT
|
||||||
|
void test_panic_halt(void);
|
||||||
|
#endif /* CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -126,6 +126,9 @@ void app_main(void)
|
|||||||
HANDLE_TEST(test_name, test_tcb_corrupted);
|
HANDLE_TEST(test_name, test_tcb_corrupted);
|
||||||
HANDLE_TEST(test_name, test_panic_handler_stuck0);
|
HANDLE_TEST(test_name, test_panic_handler_stuck0);
|
||||||
HANDLE_TEST(test_name, test_panic_handler_crash0);
|
HANDLE_TEST(test_name, test_panic_handler_crash0);
|
||||||
|
#if CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT
|
||||||
|
HANDLE_TEST(test_name, test_panic_halt);
|
||||||
|
#endif /* CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT */
|
||||||
#if CONFIG_ESP_SYSTEM_USE_FRAME_POINTER
|
#if CONFIG_ESP_SYSTEM_USE_FRAME_POINTER
|
||||||
HANDLE_TEST(test_name, test_panic_print_backtrace);
|
HANDLE_TEST(test_name, test_panic_print_backtrace);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -445,3 +445,12 @@ void test_panic_print_backtrace(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT
|
||||||
|
void test_panic_halt(void)
|
||||||
|
{
|
||||||
|
printf("Triggering panic. Device should print 'CPU halted.' and stop.\n");
|
||||||
|
fflush(stdout);
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT */
|
||||||
|
@@ -2,12 +2,9 @@
|
|||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
import itertools
|
import itertools
|
||||||
import re
|
import re
|
||||||
|
from collections.abc import Sequence
|
||||||
|
from re import Pattern
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import List
|
|
||||||
from typing import Optional
|
|
||||||
from typing import Pattern
|
|
||||||
from typing import Sequence
|
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
import pexpect
|
import pexpect
|
||||||
import pytest
|
import pytest
|
||||||
@@ -48,6 +45,7 @@ CONFIGS = list(
|
|||||||
|
|
||||||
CONFIG_PANIC = list(itertools.chain(itertools.product(['panic'], ['supported_targets'])))
|
CONFIG_PANIC = list(itertools.chain(itertools.product(['panic'], ['supported_targets'])))
|
||||||
CONFIG_PANIC_DUAL_CORE = list(itertools.chain(itertools.product(['panic'], TARGETS_DUAL_CORE)))
|
CONFIG_PANIC_DUAL_CORE = list(itertools.chain(itertools.product(['panic'], TARGETS_DUAL_CORE)))
|
||||||
|
CONFIG_PANIC_HALT = list(itertools.chain(itertools.product(['panic_halt'], TARGETS_ALL)))
|
||||||
|
|
||||||
CONFIGS_BACKTRACE = list(
|
CONFIGS_BACKTRACE = list(
|
||||||
itertools.chain(
|
itertools.chain(
|
||||||
@@ -105,11 +103,11 @@ CONFIG_COREDUMP_SUMMARY_FLASH_ENCRYPTED = list(
|
|||||||
PANIC_ABORT_PREFIX = 'Panic reason: '
|
PANIC_ABORT_PREFIX = 'Panic reason: '
|
||||||
|
|
||||||
|
|
||||||
def get_default_backtrace(config: str) -> List[str]:
|
def get_default_backtrace(config: str) -> list[str]:
|
||||||
return [config, 'app_main', 'main_task', 'vPortTaskWrapper']
|
return [config, 'app_main', 'main_task', 'vPortTaskWrapper']
|
||||||
|
|
||||||
|
|
||||||
def expect_coredump_flash_write_logs(dut: PanicTestDut, config: str, check_cpu_reset: Optional[bool] = True) -> None:
|
def expect_coredump_flash_write_logs(dut: PanicTestDut, config: str, check_cpu_reset: bool | None = True) -> None:
|
||||||
dut.expect_exact('Save core dump to flash...')
|
dut.expect_exact('Save core dump to flash...')
|
||||||
if 'extram_stack' in config:
|
if 'extram_stack' in config:
|
||||||
dut.expect_exact('Backing up stack @')
|
dut.expect_exact('Backing up stack @')
|
||||||
@@ -120,7 +118,7 @@ def expect_coredump_flash_write_logs(dut: PanicTestDut, config: str, check_cpu_r
|
|||||||
dut.expect_cpu_reset()
|
dut.expect_cpu_reset()
|
||||||
|
|
||||||
|
|
||||||
def expect_coredump_uart_write_logs(dut: PanicTestDut, check_cpu_reset: Optional[bool] = True) -> Any:
|
def expect_coredump_uart_write_logs(dut: PanicTestDut, check_cpu_reset: bool | None = True) -> Any:
|
||||||
# ================= CORE DUMP START =================
|
# ================= CORE DUMP START =================
|
||||||
# B8AAAMAEgAGAAAAXAEAAAAAAABkAAAA
|
# B8AAAMAEgAGAAAAXAEAAAAAAABkAAAA
|
||||||
# ...
|
# ...
|
||||||
@@ -144,9 +142,9 @@ def expect_coredump_uart_write_logs(dut: PanicTestDut, check_cpu_reset: Optional
|
|||||||
def common_test(
|
def common_test(
|
||||||
dut: PanicTestDut,
|
dut: PanicTestDut,
|
||||||
config: str,
|
config: str,
|
||||||
expected_backtrace: Optional[List[str]] = None,
|
expected_backtrace: list[str] | None = None,
|
||||||
check_cpu_reset: Optional[bool] = True,
|
check_cpu_reset: bool | None = True,
|
||||||
expected_coredump: Optional[Sequence[Union[str, Pattern[Any]]]] = None,
|
expected_coredump: Sequence[str | Pattern[Any]] | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if 'gdbstub' in config:
|
if 'gdbstub' in config:
|
||||||
if 'coredump' in config:
|
if 'coredump' in config:
|
||||||
@@ -1245,3 +1243,11 @@ def test_panic_print_backtrace(dut: PanicTestDut, config: str, test_func_name: s
|
|||||||
|
|
||||||
coredump_pattern = re.compile(PANIC_ABORT_PREFIX + regex_pattern.decode('utf-8'))
|
coredump_pattern = re.compile(PANIC_ABORT_PREFIX + regex_pattern.decode('utf-8'))
|
||||||
common_test(dut, config, expected_backtrace=None, expected_coredump=[coredump_pattern])
|
common_test(dut, config, expected_backtrace=None, expected_coredump=[coredump_pattern])
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@idf_parametrize('config, target', CONFIG_PANIC_HALT, indirect=['config', 'target'])
|
||||||
|
def test_panic_halt(dut: PanicTestDut) -> None:
|
||||||
|
dut.run_test_func('test_panic_halt')
|
||||||
|
dut.expect_exact('CPU halted.', timeout=30)
|
||||||
|
dut.expect_none(dut.REBOOT, timeout=3)
|
||||||
|
5
tools/test_apps/system/panic/sdkconfig.ci.panic_halt
Normal file
5
tools/test_apps/system/panic/sdkconfig.ci.panic_halt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Panic halt CI config
|
||||||
|
CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y
|
||||||
|
CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=n
|
||||||
|
CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT=n
|
||||||
|
CONFIG_ESP_SYSTEM_PANIC_GDBSTUB=n
|
Reference in New Issue
Block a user