forked from espressif/esp-idf
fix(coredump): properly save task's stack when stack is located in PSRAM
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
#ifdef CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF
|
#ifdef CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF
|
||||||
#include <sys/param.h> // for the MIN macro
|
#include <sys/param.h> // for the MIN macro
|
||||||
#include "esp_app_desc.h"
|
#include "esp_app_desc.h"
|
||||||
|
#include "esp_memory_utils.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ELF_CLASS ELFCLASS32
|
#define ELF_CLASS ELFCLASS32
|
||||||
@@ -300,22 +301,6 @@ static int elf_add_regs(core_dump_elf_t *self, core_dump_task_header_t *task)
|
|||||||
len);
|
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)
|
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.");
|
ELF_CHECK_ERR((task), ELF_PROC_ERR_OTHER, "Invalid task pointer.");
|
||||||
@@ -348,17 +333,34 @@ 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)
|
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, stack_len = 0, stack_paddr = 0;
|
||||||
|
|
||||||
ELF_CHECK_ERR((task), ELF_PROC_ERR_OTHER, "Invalid input data.");
|
ELF_CHECK_ERR((task), ELF_PROC_ERR_OTHER, "Invalid input data.");
|
||||||
|
|
||||||
ret = elf_add_stack(self, task);
|
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
|
||||||
|
/* If the task data located in the PSRAM, we will save it here.
|
||||||
|
Otherwise it will be saved in esp_core_dump_store_section()
|
||||||
|
*/
|
||||||
|
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) {
|
if (ret <= 0) {
|
||||||
ESP_COREDUMP_LOGE("Task (TCB:%x), (Stack:%x), stack processing failure = %d.",
|
ESP_COREDUMP_LOGE("Task (TCB:%x), (Stack:%x), stack processing failure = %d.",
|
||||||
task->tcb_addr,
|
task->tcb_addr,
|
||||||
task->stack_start,
|
task->stack_start,
|
||||||
ret);
|
ret);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,20 +455,13 @@ static int elf_save_task(core_dump_elf_t *self, core_dump_task_header_t *task)
|
|||||||
return elf_len;
|
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;
|
int elf_len = 0, ret;
|
||||||
core_dump_task_header_t task_hdr = { 0 };
|
core_dump_task_header_t task_hdr = { 0 };
|
||||||
core_dump_mem_seg_header_t interrupted_stack = { 0 };
|
core_dump_mem_seg_header_t interrupted_stack = { 0 };
|
||||||
TaskIterator_t task_iter;
|
TaskIterator_t task_iter;
|
||||||
int ret = ELF_PROC_ERR_OTHER;
|
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 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 ================");
|
ESP_COREDUMP_LOG_PROCESS("================ Processing task data ================");
|
||||||
// processes all task's stack data and writes segment data into partition
|
// processes all task's stack data and writes segment data into partition
|
||||||
@@ -479,17 +474,16 @@ static int elf_write_tasks_data(core_dump_elf_t *self)
|
|||||||
bad_tasks_num++;
|
bad_tasks_num++;
|
||||||
continue;
|
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);
|
ret = elf_save_task(self, &task_hdr);
|
||||||
ELF_CHECK_ERR((ret > 0), ret,
|
ELF_CHECK_ERR((ret > 0), ret,
|
||||||
"Task %x, TCB write failed, return (%d).", task_iter.pxTaskHandle, ret);
|
"Task %x, TCB write failed, return (%d).", task_iter.pxTaskHandle, ret);
|
||||||
elf_len += 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) {
|
if (interrupted_stack.size > 0) {
|
||||||
ESP_COREDUMP_LOG_PROCESS("Add interrupted task stack %lu bytes @ %x",
|
ESP_COREDUMP_LOG_PROCESS("Add interrupted task stack %lu bytes @ %x",
|
||||||
interrupted_stack.size, interrupted_stack.start);
|
interrupted_stack.size, interrupted_stack.start);
|
||||||
@@ -500,11 +494,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_CHECK_ERR((ret > 0), ret, "Interrupted task stack write failed, return (%d).", ret);
|
||||||
elf_len += ret;
|
elf_len += ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
ESP_COREDUMP_LOG_PROCESS("Found %d bad task out of %d", bad_tasks_num, tasks_num);
|
ESP_COREDUMP_LOG_PROCESS("Found %d bad task out of %d", bad_tasks_num, tasks_num);
|
||||||
|
|
||||||
return elf_len;
|
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
|
#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM
|
||||||
|
|
||||||
/* Coredump stack will also be used by the checksum functions while saving sections.
|
/* Coredump stack will also be used by the checksum functions while saving sections.
|
||||||
|
Reference in New Issue
Block a user