test(espcoredump): fix test for corrupted TCB handling in coredump

This commit is contained in:
Erhan Kurubas
2026-01-21 08:12:02 +03:00
parent ea36d9b437
commit b95bbc34c3
3 changed files with 29 additions and 21 deletions
+4 -9
View File
@@ -17,7 +17,7 @@ if(CONFIG_TEST_MEMPROT)
endif() endif()
endif() endif()
if(NOT CONFIG_TEST_MEMPROT AND NOT CONFIG_ESP_COREDUMP_CAPTURE_DRAM AND NOT CONFIG_SPIRAM) if(NOT CONFIG_TEST_MEMPROT AND NOT CONFIG_ESP_COREDUMP_ENABLE AND NOT CONFIG_SPIRAM)
# Enable UBSAN checks # Enable UBSAN checks
# #
# shift-base sanitizer is disabled due to the following pattern found in register header files: # shift-base sanitizer is disabled due to the following pattern found in register header files:
@@ -32,15 +32,10 @@ if(NOT CONFIG_TEST_MEMPROT AND NOT CONFIG_ESP_COREDUMP_CAPTURE_DRAM AND NOT CONF
# Only enable UBSAN for a few components related to the panic test, # Only enable UBSAN for a few components related to the panic test,
# due to RAM size limitations. # due to RAM size limitations.
set(ubsan_components main espcoredump esp_system spi_flash set(ubsan_components main esp_system spi_flash
esp_common esp_hw_support soc hal freertos) esp_common esp_hw_support soc hal freertos)
if(CONFIG_ESP_COREDUMP_CHECKSUM_SHA256)
if(CONFIG_IDF_TARGET_ESP32S2) foreach(component IN LISTS ubsan_components)
# due to the ram limitation, coredump is removed from esp32s2 built
list(REMOVE_ITEM ubsan_components espcoredump)
endif()
endif()
foreach(component IN LISTS ubsan_components)
idf_component_get_property(lib ${component} COMPONENT_LIB) idf_component_get_property(lib ${component} COMPONENT_LIB)
target_compile_options(${lib} PRIVATE ${ubsan_options}) target_compile_options(${lib} PRIVATE ${ubsan_options})
endforeach() endforeach()
+14 -5
View File
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Unlicense OR CC0-1.0 * SPDX-License-Identifier: Unlicense OR CC0-1.0
*/ */
@@ -382,10 +382,19 @@ void test_coredump_summary(void)
void test_tcb_corrupted(void) void test_tcb_corrupted(void)
{ {
uint32_t *tcb_ptr = (uint32_t *)xTaskGetIdleTaskHandleForCore(0); StaticTask_t *tcb = (StaticTask_t *)xTaskGetIdleTaskHandleForCore(0);
for (size_t i = 0; i < sizeof(StaticTask_t) / sizeof(uint32_t); ++i) {
tcb_ptr[i] = 0xDEADBEE0; // Corrupt critical fields that are read by xTaskGetNext() and vTaskGetSnapshot().
} tcb->pxDummy1 = (void *)0xDEADBEE0; // pxTopOfStack
tcb->xDummy3[0].pvDummy3[0] = (void *)0xDEADBEE1; // xStateListItem.pxNext
tcb->xDummy3[0].pvDummy3[1] = (void *)0xDEADBEE2; // xStateListItem.pxPrevious
tcb->xDummy3[0].pvDummy3[2] = (void *)0xDEADBEE3; // xStateListItem.pvOwner
tcb->pxDummy6 = (void *)0xDEADBEE6; // pxStack
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
tcb->pxDummy8 = (void *)0xDEADBEE8; // pxEndOfStack
#endif
// Trigger a context switch.
vTaskDelay(2); vTaskDelay(2);
} }
+11 -7
View File
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
import re import re
from typing import Any from typing import Any
@@ -57,6 +57,11 @@ CONFIGS = [
pytest.param('panic', marks=TARGETS_ALL), pytest.param('panic', marks=TARGETS_ALL),
] ]
CONFIGS_UBSAN = [
pytest.param('gdbstub', marks=TARGETS_ALL),
pytest.param('panic', marks=TARGETS_ALL),
]
CONFIGS_DUAL_CORE = [ CONFIGS_DUAL_CORE = [
pytest.param('coredump_flash_bin_crc', marks=TARGETS_DUAL_CORE), pytest.param('coredump_flash_bin_crc', marks=TARGETS_DUAL_CORE),
pytest.param('coredump_flash_elf_sha', marks=TARGETS_DUAL_CORE), pytest.param('coredump_flash_elf_sha', marks=TARGETS_DUAL_CORE),
@@ -480,7 +485,7 @@ def test_abort(dut: PanicTestDut, config: str, test_func_name: str) -> None:
) )
@pytest.mark.parametrize('config', CONFIGS, indirect=True) @pytest.mark.parametrize('config', CONFIGS_UBSAN, indirect=True)
@pytest.mark.generic @pytest.mark.generic
def test_ub(dut: PanicTestDut, config: str, test_func_name: str) -> None: def test_ub(dut: PanicTestDut, config: str, test_func_name: str) -> None:
dut.run_test_func(test_func_name) dut.run_test_func(test_func_name)
@@ -493,7 +498,6 @@ def test_ub(dut: PanicTestDut, config: str, test_func_name: str) -> None:
dut.expect_elf_sha256() dut.expect_elf_sha256()
dut.expect_none(['Guru Meditation', 'Re-entered core dump']) dut.expect_none(['Guru Meditation', 'Re-entered core dump'])
coredump_pattern = re.compile(PANIC_ABORT_PREFIX + regex_pattern.decode('utf-8'))
common_test( common_test(
dut, dut,
config, config,
@@ -502,8 +506,7 @@ def test_ub(dut: PanicTestDut, config: str, test_func_name: str) -> None:
'esp_system_abort', 'esp_system_abort',
'__ubsan_default_handler', '__ubsan_default_handler',
'__ubsan_handle_out_of_bounds' '__ubsan_handle_out_of_bounds'
] + get_default_backtrace(test_func_name), ] + get_default_backtrace(test_func_name)
expected_coredump=[coredump_pattern]
) )
@@ -1195,17 +1198,18 @@ def test_coredump_summary_flash_encrypted(dut: PanicTestDut, config: str) -> Non
def test_tcb_corrupted(dut: PanicTestDut, target: str, config: str, test_func_name: str) -> None: def test_tcb_corrupted(dut: PanicTestDut, target: str, config: str, test_func_name: str) -> None:
dut.run_test_func(test_func_name) dut.run_test_func(test_func_name)
if dut.is_xtensa: if dut.is_xtensa:
dut.expect_gme('LoadProhibited') dut.expect(re.compile(rb"Guru Meditation Error: Core\s+\d\s+panic'ed \((LoadProhibited|StoreProhibited)\)"))
dut.expect_reg_dump() dut.expect_reg_dump()
dut.expect_backtrace() dut.expect_backtrace()
else: else:
dut.expect_gme('Load access fault') dut.expect(re.compile(rb"Guru Meditation Error: Core\s+\d\s+panic'ed \((Load|Store) access fault\)"))
dut.expect_reg_dump() dut.expect_reg_dump()
dut.expect_stack_dump() dut.expect_stack_dump()
dut.expect_elf_sha256() dut.expect_elf_sha256()
dut.expect_none('Guru Meditation') dut.expect_none('Guru Meditation')
# Verify that valid tasks are captured in coredump despite IDLE task corruption
# TCB NAME # TCB NAME
# ---------- ---------------- # ---------- ----------------
if dut.is_multi_core: if dut.is_multi_core: