fix(coredump): implement CONFIG_ESP_COREDUMP_MAX_TASKS_NUM limitation

This commit is contained in:
Erhan Kurubas
2025-08-14 14:16:53 +03:00
parent 1bb2d5c8a6
commit c03d98b5f3
4 changed files with 63 additions and 21 deletions
+3 -1
View File
@@ -74,7 +74,9 @@ menu "Core dump"
depends on ESP_COREDUMP_ENABLE
default 64
help
Maximum number of tasks snapshots in core dump.
Maximum number of tasks that will be included in the core dump.
Crashed task registers and stacks are always included.
Other tasks are included in order of their priority. (Highest priority ready task first)
config ESP_COREDUMP_UART_DELAY
int "Delay before print to UART"
+58 -16
View File
@@ -410,6 +410,7 @@ static int elf_process_tasks_regs(core_dump_elf_t *self)
void *task = NULL;
int len = 0;
int ret = 0;
int tasks_num = 0;
esp_core_dump_reset_tasks_snapshots_iter();
task = esp_core_dump_get_current_task_handle();
@@ -423,6 +424,7 @@ static int elf_process_tasks_regs(core_dump_elf_t *self)
ELF_CHECK_ERR((ret > 0), ret, "Task %x, PR_STATUS write failed, return (%d).", task, ret);
}
len += ret;
tasks_num++;
}
// processes PR_STATUS and register dump for each task
// each call to the processing function appends PR_STATUS note into note segment
@@ -430,8 +432,14 @@ static int elf_process_tasks_regs(core_dump_elf_t *self)
esp_core_dump_task_iterator_init(&task_iter);
while (esp_core_dump_task_iterator_next(&task_iter) != -1) {
task = task_iter.pxTaskHandle;
if (!task || task == esp_core_dump_get_current_task_handle()) // skip current task (already processed)
if (!task || task == esp_core_dump_get_current_task_handle()) { // skip current task (already processed)
continue;
}
if (tasks_num > CONFIG_ESP_COREDUMP_MAX_TASKS_NUM) {
ESP_COREDUMP_LOG_PROCESS("Reached maximum number of tasks (%d), stopping task register processing",
CONFIG_ESP_COREDUMP_MAX_TASKS_NUM);
break;
}
if (esp_core_dump_get_task_snapshot(task, &task_hdr, NULL)) {
ret = elf_add_regs(self, &task_hdr);
if (self->elf_stage == ELF_STAGE_PLACE_HEADERS) {
@@ -441,6 +449,7 @@ static int elf_process_tasks_regs(core_dump_elf_t *self)
ELF_CHECK_ERR((ret > 0), ret, "Task %x, PR_STATUS write failed, return (%d).", task, ret);
}
len += ret;
tasks_num++;
}
}
ret = elf_process_note_segment(self, len); // tasks regs note
@@ -464,6 +473,25 @@ static int elf_save_task(core_dump_elf_t *self, core_dump_task_header_t *task)
return elf_len;
}
static int elf_save_interrupted_stack(core_dump_elf_t *self, core_dump_mem_seg_header_t *interrupted_stack)
{
int ret = 0;
/* interrupt stacks:
- 'port_IntStack' is in the data section for xtensa
- 'xIsrStack' is in the bss section for risc-v
*/
if (interrupted_stack->size > 0) {
ESP_COREDUMP_LOG_PROCESS("Add interrupted task stack %lu bytes @ %x",
interrupted_stack->size, interrupted_stack->start);
ret = elf_add_segment(self, PT_LOAD,
(uint32_t)interrupted_stack->start,
(void*)interrupted_stack->start,
(uint32_t)interrupted_stack->size);
ELF_CHECK_ERR((ret > 0), ret, "Interrupted task stack write failed, return (%d).", ret);
}
return ret;
}
static int elf_write_tasks_data(core_dump_elf_t *self)
{
int elf_len = 0;
@@ -471,8 +499,8 @@ static int elf_write_tasks_data(core_dump_elf_t *self)
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;
int tasks_num = 0;
int bad_tasks_num = 0;
ESP_COREDUMP_LOG_PROCESS("================ Processing task registers ================");
ret = elf_process_tasks_regs(self);
@@ -480,13 +508,37 @@ static int elf_write_tasks_data(core_dump_elf_t *self)
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
// first write crashed task data
esp_core_dump_reset_tasks_snapshots_iter();
void *current_task = esp_core_dump_get_current_task_handle();
if (esp_core_dump_get_task_snapshot(current_task, &task_hdr, &interrupted_stack)) {
int ret = elf_save_task(self, &task_hdr);
ELF_CHECK_ERR((ret > 0), ret,
"Task %x, TCB write failed, return (%d).", current_task, ret);
elf_len += ret;
// Handle interrupted stack (only relevant for current task)
ret = elf_save_interrupted_stack(self, &interrupted_stack);
if (ret > 0) {
elf_len += ret;
}
tasks_num++;
}
esp_core_dump_task_iterator_init(&task_iter);
while (esp_core_dump_task_iterator_next(&task_iter) != -1) {
// Skip the current task (already processed above)
if (!task_iter.pxTaskHandle || task_iter.pxTaskHandle == current_task) {
continue;
}
if (tasks_num > CONFIG_ESP_COREDUMP_MAX_TASKS_NUM) {
ESP_COREDUMP_LOG_PROCESS("Reached maximum number of tasks (%d), stopping task data processing",
CONFIG_ESP_COREDUMP_MAX_TASKS_NUM);
break;
}
tasks_num++;
if (!esp_core_dump_get_task_snapshot(task_iter.pxTaskHandle, &task_hdr, &interrupted_stack)) {
if (!esp_core_dump_get_task_snapshot(task_iter.pxTaskHandle, &task_hdr, NULL)) {
bad_tasks_num++;
continue;
}
@@ -494,16 +546,6 @@ static int elf_write_tasks_data(core_dump_elf_t *self)
ELF_CHECK_ERR((ret > 0), ret,
"Task %x, TCB write failed, return (%d).", task_iter.pxTaskHandle, ret);
elf_len += ret;
if (interrupted_stack.size > 0) {
ESP_COREDUMP_LOG_PROCESS("Add interrupted task stack %lu bytes @ %x",
interrupted_stack.size, interrupted_stack.start);
ret = elf_add_segment(self, PT_LOAD,
(uint32_t)interrupted_stack.start,
(void*)interrupted_stack.start,
(uint32_t)interrupted_stack.size);
ELF_CHECK_ERR((ret > 0), ret, "Interrupted task stack write failed, return (%d).", ret);
elf_len += ret;
}
}
ESP_COREDUMP_LOG_PROCESS("Found %d bad task out of %d", bad_tasks_num, tasks_num);
return elf_len;