Skip to content

Commit

Permalink
ci(panic): extend extram_stack tests
Browse files Browse the repository at this point in the history
  • Loading branch information
erhankur committed May 27, 2024
1 parent 1dd4b95 commit 002faf3
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 21 deletions.
18 changes: 12 additions & 6 deletions components/espcoredump/src/core_dump_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,9 @@ static int elf_process_task_tcb(core_dump_elf_t *self, core_dump_task_header_t *
static int elf_process_task_stack(core_dump_elf_t *self, core_dump_task_header_t *task)
{
int ret = 0;
uint32_t stack_vaddr, stack_len = 0, stack_paddr = 0;
uint32_t stack_vaddr;
uint32_t stack_len = 0;
uint32_t stack_paddr = 0;

ELF_CHECK_ERR((task), ELF_PROC_ERR_OTHER, "Invalid input data.");

Expand All @@ -343,8 +345,11 @@ static int elf_process_task_stack(core_dump_elf_t *self, core_dump_task_header_t
task->tcb_addr, stack_vaddr, stack_len);

#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM
/* If the task data located in the PSRAM, we will save it here.
Otherwise it will be saved in esp_core_dump_store_section()
/*
When saving all data sections (enabled by `CONFIG_ESP_COREDUMP_CAPTURE_DRAM`),
the task stack located in DRAM will be saved in `esp_core_dump_store_section()`.
Therefore, we filter them out here.
PSRAM data do not fall into any ELF section, so we always save such stacks here.
*/
if (esp_ptr_external_ram((void *)stack_vaddr))
#endif
Expand Down Expand Up @@ -457,11 +462,12 @@ static int elf_save_task(core_dump_elf_t *self, core_dump_task_header_t *task)

static int elf_process_task_data(core_dump_elf_t *self)
{
int elf_len = 0, ret;
int elf_len = 0;
core_dump_task_header_t task_hdr = { 0 };
core_dump_mem_seg_header_t interrupted_stack = { 0 };
TaskIterator_t task_iter;
uint16_t tasks_num = 0, bad_tasks_num = 0;
uint16_t tasks_num = 0;
uint16_t bad_tasks_num = 0;

ESP_COREDUMP_LOG_PROCESS("================ Processing task data ================");
// processes all task's stack data and writes segment data into partition
Expand All @@ -474,7 +480,7 @@ static int elf_process_task_data(core_dump_elf_t *self)
bad_tasks_num++;
continue;
}
ret = elf_save_task(self, &task_hdr);
int ret = elf_save_task(self, &task_hdr);
ELF_CHECK_ERR((ret > 0), ret,
"Task %x, TCB write failed, return (%d).", task_iter.pxTaskHandle, ret);
elf_len += ret;
Expand Down
2 changes: 1 addition & 1 deletion tools/test_apps/system/panic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ if(CONFIG_TEST_MEMPROT)
endif()
endif()

if(NOT CONFIG_TEST_MEMPROT AND NOT CONFIG_ESP_COREDUMP_CAPTURE_DRAM)
if(NOT CONFIG_TEST_MEMPROT AND NOT CONFIG_ESP_COREDUMP_CAPTURE_DRAM AND NOT CONFIG_SPIRAM)
# Enable UBSAN checks
#
# shift-base sanitizer is disabled due to the following pattern found in register header files:
Expand Down
4 changes: 2 additions & 2 deletions tools/test_apps/system/panic/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ endif()

idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "include"
REQUIRES spi_flash esp_psram esp_system esp_partition espcoredump
PRIV_REQUIRES esp_gdbstub)
REQUIRES spi_flash esp_psram esp_system esp_partition
PRIV_REQUIRES esp_gdbstub espcoredump)

target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-unused-variable"
"-Wno-infinite-recursion"
Expand Down
5 changes: 4 additions & 1 deletion tools/test_apps/system/panic/main/include/test_panic.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ void test_hw_stack_guard_cpu1(void);
#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD

#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
void test_panic_extram_stack(void);
void test_panic_extram_stack_heap(void);
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
void test_panic_extram_stack_bss(void);
#endif
#endif

#if !CONFIG_FREERTOS_UNICORE
Expand Down
5 changes: 4 additions & 1 deletion tools/test_apps/system/panic/main/test_app_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ void app_main(void)
#endif // CONFIG_FREERTOS_UNICORE
#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD
#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
HANDLE_TEST(test_name, test_panic_extram_stack);
HANDLE_TEST(test_name, test_panic_extram_stack_heap);
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
HANDLE_TEST(test_name, test_panic_extram_stack_bss);
#endif
#endif
#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM
HANDLE_TEST(test_name, test_capture_dram);
Expand Down
11 changes: 10 additions & 1 deletion tools/test_apps/system/panic/main/test_panic.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ static void stack_in_extram(void* arg) {
abort();
}

void test_panic_extram_stack(void) {
void test_panic_extram_stack_heap(void) {
/* Start by initializing a Task which has a stack in external RAM */
StaticTask_t handle;
const uint32_t stack_size = 8192;
Expand All @@ -119,8 +119,17 @@ void test_panic_extram_stack(void) {

vTaskDelay(1000);
}
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
static EXT_RAM_BSS_ATTR StackType_t stack[8192];
void test_panic_extram_stack_bss(void)
{
StaticTask_t handle;

xTaskCreateStatic(stack_in_extram, "Task_stack_extram", sizeof(stack), NULL, 4, stack, &handle);

vTaskDelay(1000);
}
#endif
#endif // ESP_COREDUMP_ENABLE_TO_FLASH && SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY


Expand Down
34 changes: 27 additions & 7 deletions tools/test_apps/system/panic/pytest_panic.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,13 @@
# This list is used to check if the target is a dual-core one.
TARGETS_DUAL_CORE_NAMES = [x.mark.name for x in TARGETS_DUAL_CORE]

# The tests which panic on external stack require PSRAM capable runners
CONFIGS_EXTRAM_STACK = [
pytest.param('coredump_extram_stack', marks=[pytest.mark.esp32, pytest.mark.psram]),
pytest.param('coredump_extram_stack', marks=[pytest.mark.esp32s2, pytest.mark.generic]),
pytest.param('coredump_extram_stack', marks=[pytest.mark.esp32s3, pytest.mark.quad_psram]),
pytest.param('coredump_flash_extram_stack_heap_esp32', marks=[pytest.mark.esp32, pytest.mark.psram]),
pytest.param('coredump_flash_extram_stack_heap_esp32s2', marks=[pytest.mark.esp32s2, pytest.mark.generic]),
pytest.param('coredump_flash_extram_stack_heap_esp32s3', marks=[pytest.mark.esp32s3, pytest.mark.quad_psram]),
pytest.param('coredump_flash_extram_stack_bss_esp32', marks=[pytest.mark.esp32, pytest.mark.psram]),
pytest.param('coredump_flash_extram_stack_bss_esp32s2', marks=[pytest.mark.esp32s2, pytest.mark.generic]),
pytest.param('coredump_flash_extram_stack_bss_esp32s3', marks=[pytest.mark.esp32s3, pytest.mark.quad_psram]),
]

CONFIGS_HW_STACK_GUARD = [
Expand Down Expand Up @@ -207,8 +209,11 @@ def test_task_wdt_cpu1(dut: PanicTestDut, config: str, test_func_name: str) -> N


@pytest.mark.parametrize('config', CONFIGS_EXTRAM_STACK, indirect=True)
def test_panic_extram_stack(dut: PanicTestDut, config: str, test_func_name: str) -> None:
dut.run_test_func(test_func_name)
def test_panic_extram_stack(dut: PanicTestDut, config: str) -> None:
if 'heap' in config:
dut.run_test_func('test_panic_extram_stack_heap')
else:
dut.run_test_func('test_panic_extram_stack_bss')
dut.expect_none('Allocated stack is not in external RAM')
dut.expect_none('Guru Meditation')
dut.expect_backtrace()
Expand All @@ -221,7 +226,22 @@ def test_panic_extram_stack(dut: PanicTestDut, config: str, test_func_name: str)
# The caller must be accessible after restoring the stack
dut.expect_exact('Core dump has been saved to flash.')

common_test(dut, config)
if dut.target == 'esp32':
# ESP32 External data memory range [0x3f800000-0x3fc00000)
coredump_pattern = re.compile('.coredump.tasks.data (0x3[fF][8-9a-bA-B][0-9a-fA-F]{5}) (0x[a-fA-F0-9]+) RW')
elif dut.target == 'esp32s2':
# ESP32-S2 External data memory range [0x3f500000-0x3ff80000)
coredump_pattern = re.compile('.coredump.tasks.data (0x3[fF][5-9a-fA-F][0-7][0-9a-fA-F]{4}) (0x[a-fA-F0-9]+) RW')
else:
# ESP32-S3 External data memory range [0x3c000000-0x3e000000)
coredump_pattern = re.compile('.coredump.tasks.data (0x3[c-dC-D][0-9a-fA-F]{6}) (0x[a-fA-F0-9]+) RW')

common_test(
dut,
config,
expected_backtrace=None,
expected_coredump=[coredump_pattern]
)


@pytest.mark.parametrize('config', CONFIGS, indirect=True)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y
CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y
# We need to have the coredump info log
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
CONFIG_ESP_COREDUMP_USE_STACK_SIZE=y
CONFIG_ESP_COREDUMP_CAPTURE_DRAM=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_capture_dram.csv"
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CONFIG_IDF_TARGET="esp32s2"
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y
CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y
# We need to have the coredump info log
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
CONFIG_ESP_COREDUMP_USE_STACK_SIZE=y
CONFIG_ESP_COREDUMP_CAPTURE_DRAM=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_capture_dram.csv"
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y
CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y
# We need to have the coredump info log
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
CONFIG_ESP_COREDUMP_USE_STACK_SIZE=y
CONFIG_ESP_COREDUMP_CAPTURE_DRAM=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_capture_dram.csv"
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ CONFIG_IDF_TARGET="esp32"
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y
CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y
# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set
CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y
# We need to have the coredump info log
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
CONFIG_SPIRAM=y
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CONFIG_IDF_TARGET="esp32s2"
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y
CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y
# We need to have the coredump info log
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y
CONFIG_ESP_COREDUMP_USE_STACK_SIZE=y
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y
CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y
# We need to have the coredump info log
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y
CONFIG_ESP_COREDUMP_USE_STACK_SIZE=y

0 comments on commit 002faf3

Please sign in to comment.