Skip to content

Commit

Permalink
Merge branch 'extend_coredump_tests_v5.3' into 'release/v5.3'
Browse files Browse the repository at this point in the history
Extend coredump tests v5.3

See merge request espressif/esp-idf!33456
  • Loading branch information
gerekon committed Dec 10, 2024
2 parents aabab37 + dfc248d commit 9d3917d
Show file tree
Hide file tree
Showing 16 changed files with 253 additions and 94 deletions.
99 changes: 58 additions & 41 deletions components/espcoredump/src/core_dump_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifdef CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF
#include <sys/param.h> // for the MIN macro
#include "esp_app_desc.h"
#include "esp_memory_utils.h"
#endif

#define ELF_CLASS ELFCLASS32
Expand Down Expand Up @@ -300,22 +301,6 @@ static int elf_add_regs(core_dump_elf_t *self, core_dump_task_header_t *task)
len);
}

static int elf_add_stack(core_dump_elf_t *self, core_dump_task_header_t *task)
{
uint32_t stack_vaddr, stack_len = 0, stack_paddr = 0;

ELF_CHECK_ERR((task), ELF_PROC_ERR_OTHER, "Invalid task pointer.");

stack_len = esp_core_dump_get_stack(task, &stack_vaddr, &stack_paddr);
ESP_COREDUMP_LOG_PROCESS("Add stack for task 0x%x: addr 0x%x, sz %u",
task->tcb_addr, stack_vaddr, stack_len);
int ret = elf_add_segment(self, PT_LOAD,
(uint32_t)stack_vaddr,
(void*)stack_paddr,
(uint32_t) stack_len);
return ret;
}

static int elf_add_tcb(core_dump_elf_t *self, core_dump_task_header_t *task)
{
ELF_CHECK_ERR((task), ELF_PROC_ERR_OTHER, "Invalid task pointer.");
Expand Down Expand Up @@ -348,17 +333,39 @@ 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 = ELF_PROC_ERR_OTHER;
int ret = 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.");

ret = elf_add_stack(self, task);
if (ret <= 0) {
ESP_COREDUMP_LOGE("Task (TCB:%x), (Stack:%x), stack processing failure = %d.",
task->tcb_addr,
task->stack_start,
ret);
stack_len = esp_core_dump_get_stack(task, &stack_vaddr, &stack_paddr);
ESP_COREDUMP_LOG_PROCESS("Add stack for task 0x%x: addr 0x%x, sz %u",
task->tcb_addr, stack_vaddr, stack_len);

#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM
/*
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
{
ret = elf_add_segment(self, PT_LOAD,
(uint32_t)stack_vaddr,
(void*)stack_paddr,
(uint32_t) stack_len);
if (ret <= 0) {
ESP_COREDUMP_LOGE("Task (TCB:%x), (Stack:%x), stack processing failure = %d.",
task->tcb_addr,
task->stack_start,
ret);
}
}

return ret;
}

Expand Down Expand Up @@ -453,21 +460,15 @@ static int elf_save_task(core_dump_elf_t *self, core_dump_task_header_t *task)
return elf_len;
}

static int elf_write_tasks_data(core_dump_elf_t *self)
static int elf_process_task_data(core_dump_elf_t *self)
{
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;
int ret = ELF_PROC_ERR_OTHER;
uint16_t tasks_num = 0;
uint16_t bad_tasks_num = 0;

ESP_COREDUMP_LOG_PROCESS("================ Processing task registers ================");
ret = elf_process_tasks_regs(self);
ELF_CHECK_ERR((ret > 0), ret, "Tasks regs addition failed, return (%d).", ret);
elf_len += ret;

ESP_COREDUMP_LOG_PROCESS("================ Processing task data ================");
// processes all task's stack data and writes segment data into partition
// if flash configuration is set
Expand All @@ -479,17 +480,16 @@ static int elf_write_tasks_data(core_dump_elf_t *self)
bad_tasks_num++;
continue;
}

#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM
/* Only crashed task data will be saved here. The other task's data will be automatically saved within the sections */
if (esp_core_dump_get_current_task_handle() == task_iter.pxTaskHandle)
#endif
{
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;
}
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;
/* interrupt stacks:
- 'port_IntStack' is in the data section for xtensa
- 'xIsrStack' is in the bss section for risc-v
When DRAM capture is enabled, interrupt stack saving can be done during the full section store
*/
#if !CONFIG_ESP_COREDUMP_CAPTURE_DRAM
if (interrupted_stack.size > 0) {
ESP_COREDUMP_LOG_PROCESS("Add interrupted task stack %lu bytes @ %x",
interrupted_stack.size, interrupted_stack.start);
Expand All @@ -500,11 +500,28 @@ static int elf_write_tasks_data(core_dump_elf_t *self)
ELF_CHECK_ERR((ret > 0), ret, "Interrupted task stack write failed, return (%d).", ret);
elf_len += ret;
}
#endif
}
ESP_COREDUMP_LOG_PROCESS("Found %d bad task out of %d", bad_tasks_num, tasks_num);

return elf_len;
}

static int elf_write_tasks_data(core_dump_elf_t *self)
{
ESP_COREDUMP_LOG_PROCESS("================ Processing task registers ================");
int ret = elf_process_tasks_regs(self);
ELF_CHECK_ERR((ret > 0), ret, "Tasks regs addition failed, return (%d).", ret);
int elf_len = ret;

ret = elf_process_task_data(self);
if (ret <= 0) {
return ret;
}

return elf_len + ret;
}

#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM

/* Coredump stack will also be used by the checksum functions while saving sections.
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
7 changes: 6 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 Expand Up @@ -67,6 +70,8 @@ void test_illegal_access(void);

void test_capture_dram(void);

void test_tcb_corrupted(void);

#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF
void test_setup_coredump_summary(void);
void test_coredump_summary(void);
Expand Down
6 changes: 5 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 All @@ -116,6 +119,7 @@ void app_main(void)
HANDLE_TEST(test_name, test_assert_cache_disabled);
HANDLE_TEST(test_name, test_assert_cache_write_back_error_can_print_backtrace);
HANDLE_TEST(test_name, test_assert_cache_write_back_error_can_print_backtrace2);
HANDLE_TEST(test_name, test_tcb_corrupted);
#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF
HANDLE_TEST(test_name, test_setup_coredump_summary);
HANDLE_TEST(test_name, test_coredump_summary);
Expand Down
20 changes: 19 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 Expand Up @@ -301,6 +310,15 @@ void test_coredump_summary(void)
}
#endif

void test_tcb_corrupted(void)
{
uint32_t *tcb_ptr = (uint32_t *)xTaskGetIdleTaskHandleForCore(0);
for (size_t i = 0; i < sizeof(StaticTask_t) / sizeof(uint32_t); ++i) {
tcb_ptr[i] = 0xDEADBEE0;
}
vTaskDelay(2);
}

/* NOTE: The following test verifies the behaviour for the
* Xtensa-specific MPU instructions (Refer WDTLB, DSYNC, WDTIB, ISYNC)
* used for memory protection.
Expand Down
Loading

0 comments on commit 9d3917d

Please sign in to comment.