coredump: Fixes coredump data overwriting due to 'TaskSnapshot_t' and 'core_dump_task_header_t' difference
This commit is contained in:
parent
1449496fb0
commit
ef1b3330c2
4 changed files with 42 additions and 34 deletions
|
@ -42,7 +42,7 @@ extern "C" {
|
|||
#define COREDUMP_TCB_SIZE sizeof(StaticTask_t)
|
||||
|
||||
// Gets RTOS tasks snapshot
|
||||
uint32_t esp_core_dump_get_tasks_snapshot(core_dump_task_header_t* const tasks,
|
||||
uint32_t esp_core_dump_get_tasks_snapshot(core_dump_task_header_t** const tasks,
|
||||
const uint32_t snapshot_size);
|
||||
|
||||
// Checks TCB consistency
|
||||
|
|
|
@ -103,7 +103,7 @@ static esp_err_t esp_core_dump_save_mem_segment(core_dump_write_config_t* write_
|
|||
static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_t *write_cfg)
|
||||
{
|
||||
esp_err_t err;
|
||||
static core_dump_task_header_t tasks[CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM];
|
||||
static core_dump_task_header_t *tasks[CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM];
|
||||
uint32_t task_num, tcb_sz = esp_core_dump_get_tcb_len();
|
||||
uint32_t data_len = 0, task_id;
|
||||
int curr_task_index = COREDUMP_CURR_TASK_NOT_FOUND;
|
||||
|
@ -116,7 +116,7 @@ static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_
|
|||
// Verifies all tasks in the snapshot
|
||||
for (task_id = 0; task_id < task_num; task_id++) {
|
||||
bool is_current_task = false, stack_is_valid = false;
|
||||
bool tcb_is_valid = esp_core_dump_check_task(frame, &tasks[task_id], &is_current_task, &stack_is_valid);
|
||||
bool tcb_is_valid = esp_core_dump_check_task(frame, tasks[task_id], &is_current_task, &stack_is_valid);
|
||||
// Check if task tcb or stack is corrupted
|
||||
if (!tcb_is_valid || !stack_is_valid) {
|
||||
// If tcb or stack for task is corrupted count task as broken
|
||||
|
@ -126,26 +126,26 @@ static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_
|
|||
curr_task_index = task_id; // save current crashed task index in the snapshot
|
||||
ESP_COREDUMP_LOG_PROCESS("Task #%d (TCB:%x) is first crashed task.",
|
||||
task_id,
|
||||
tasks[task_id].tcb_addr);
|
||||
tasks[task_id]->tcb_addr);
|
||||
}
|
||||
// Increase core dump size by task stack size
|
||||
uint32_t stk_vaddr, stk_len;
|
||||
esp_core_dump_get_stack(&tasks[task_id], &stk_vaddr, &stk_len);
|
||||
esp_core_dump_get_stack(tasks[task_id], &stk_vaddr, &stk_len);
|
||||
data_len += esp_core_dump_get_stack_len(stk_vaddr, stk_vaddr+stk_len);
|
||||
// Add tcb size
|
||||
data_len += (tcb_sz + sizeof(core_dump_task_header_t));
|
||||
}
|
||||
|
||||
if (esp_core_dump_in_isr_context()) {
|
||||
interrupted_task_stack.start = tasks[curr_task_index].stack_start;
|
||||
interrupted_task_stack.size = esp_core_dump_get_stack_len(tasks[curr_task_index].stack_start, tasks[curr_task_index].stack_end);
|
||||
interrupted_task_stack.start = tasks[curr_task_index]->stack_start;
|
||||
interrupted_task_stack.size = esp_core_dump_get_stack_len(tasks[curr_task_index]->stack_start, tasks[curr_task_index]->stack_end);
|
||||
// size of the task's stack has been already taken into account, also addresses have also been checked
|
||||
data_len += sizeof(core_dump_mem_seg_header_t);
|
||||
tasks[curr_task_index].stack_start = (uint32_t)frame;
|
||||
tasks[curr_task_index].stack_end = esp_core_dump_get_isr_stack_end();
|
||||
ESP_COREDUMP_LOG_PROCESS("Add ISR stack %lu to %lu", tasks[curr_task_index].stack_end - tasks[curr_task_index].stack_start, data_len);
|
||||
tasks[curr_task_index]->stack_start = (uint32_t)frame;
|
||||
tasks[curr_task_index]->stack_end = esp_core_dump_get_isr_stack_end();
|
||||
ESP_COREDUMP_LOG_PROCESS("Add ISR stack %lu to %lu", tasks[curr_task_index]->stack_end - tasks[curr_task_index]->stack_start, data_len);
|
||||
// take into account size of the ISR stack
|
||||
data_len += esp_core_dump_get_stack_len(tasks[curr_task_index].stack_start, tasks[curr_task_index].stack_end);
|
||||
data_len += esp_core_dump_get_stack_len(tasks[curr_task_index]->stack_start, tasks[curr_task_index]->stack_end);
|
||||
}
|
||||
|
||||
// Check if current task TCB is broken
|
||||
|
@ -193,10 +193,10 @@ static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_
|
|||
}
|
||||
|
||||
// Write first crashed task data first (not always first task in the snapshot)
|
||||
err = esp_core_dump_save_task(write_cfg, &tasks[curr_task_index]);
|
||||
err = esp_core_dump_save_task(write_cfg, tasks[curr_task_index]);
|
||||
if (err != ESP_OK) {
|
||||
ESP_COREDUMP_LOGE("Failed to save first crashed task #%d (TCB:%x), error=%d!",
|
||||
curr_task_index, tasks[curr_task_index].tcb_addr, err);
|
||||
curr_task_index, tasks[curr_task_index]->tcb_addr, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -206,10 +206,10 @@ static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_
|
|||
if (task_id == curr_task_index) {
|
||||
continue;
|
||||
}
|
||||
err = esp_core_dump_save_task(write_cfg, &tasks[task_id]);
|
||||
err = esp_core_dump_save_task(write_cfg, tasks[task_id]);
|
||||
if (err != ESP_OK) {
|
||||
ESP_COREDUMP_LOGE("Failed to save core dump task #%d (TCB:%x), error=%d!",
|
||||
task_id, tasks[curr_task_index].tcb_addr, err);
|
||||
task_id, tasks[curr_task_index]->tcb_addr, err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -302,7 +302,7 @@ static int elf_add_tcb(core_dump_elf_t *self, core_dump_task_header_t *task)
|
|||
}
|
||||
|
||||
// get index of current crashed task (not always first task in the snapshot)
|
||||
static int elf_get_current_task_index(core_dump_task_header_t *tasks,
|
||||
static int elf_get_current_task_index(core_dump_task_header_t** tasks,
|
||||
uint32_t task_num)
|
||||
{
|
||||
int task_id;
|
||||
|
@ -311,13 +311,13 @@ static int elf_get_current_task_index(core_dump_task_header_t *tasks,
|
|||
|
||||
// get index of current crashed task (not always first task in the snapshot)
|
||||
for (task_id = 0; task_id < task_num; task_id++) {
|
||||
bool tcb_is_valid = esp_core_dump_tcb_addr_is_sane((uint32_t)tasks[task_id].tcb_addr);
|
||||
bool stack_is_valid = esp_core_dump_check_stack(tasks[task_id].stack_start, tasks[task_id].stack_end);
|
||||
if (stack_is_valid && tcb_is_valid && curr_task_handle == tasks[task_id].tcb_addr) {
|
||||
bool tcb_is_valid = esp_core_dump_tcb_addr_is_sane((uint32_t)tasks[task_id]->tcb_addr);
|
||||
bool stack_is_valid = esp_core_dump_check_stack(tasks[task_id]->stack_start, tasks[task_id]->stack_end);
|
||||
if (stack_is_valid && tcb_is_valid && curr_task_handle == tasks[task_id]->tcb_addr) {
|
||||
curr_task_index = task_id; // save current crashed task index in the snapshot
|
||||
ESP_COREDUMP_LOG_PROCESS("Task #%d, (TCB:%x) is current crashed task.",
|
||||
task_id,
|
||||
tasks[task_id].tcb_addr);
|
||||
tasks[task_id]->tcb_addr);
|
||||
}
|
||||
}
|
||||
return curr_task_index;
|
||||
|
@ -416,7 +416,7 @@ static int elf_process_note_segment(core_dump_elf_t *self, int notes_size)
|
|||
}
|
||||
|
||||
static int elf_process_tasks_regs(core_dump_elf_t *self, void* frame,
|
||||
core_dump_task_header_t* tasks,
|
||||
core_dump_task_header_t** tasks,
|
||||
uint32_t task_num)
|
||||
{
|
||||
int len = 0;
|
||||
|
@ -428,7 +428,7 @@ static int elf_process_tasks_regs(core_dump_elf_t *self, void* frame,
|
|||
}
|
||||
|
||||
// place current task dump first
|
||||
int ret = elf_process_task_regdump(self, frame, &tasks[curr_task_index]);
|
||||
int ret = elf_process_task_regdump(self, frame, tasks[curr_task_index]);
|
||||
if (self->elf_stage == ELF_STAGE_PLACE_HEADERS) {
|
||||
// when writing segments headers this function writes nothing
|
||||
ELF_CHECK_ERR((ret >= 0), ret, "Task #%d, PR_STATUS write failed, return (%d).", curr_task_index, ret);
|
||||
|
@ -444,7 +444,7 @@ static int elf_process_tasks_regs(core_dump_elf_t *self, void* frame,
|
|||
if (task_id == curr_task_index) {
|
||||
continue; // skip current task (already processed)
|
||||
}
|
||||
ret = elf_process_task_regdump(self, frame, &tasks[task_id]);
|
||||
ret = elf_process_task_regdump(self, frame, tasks[task_id]);
|
||||
if (self->elf_stage == ELF_STAGE_PLACE_HEADERS) {
|
||||
// when writing segments headers this function writes nothing
|
||||
ELF_CHECK_ERR((ret >= 0), ret, "Task #%d, PR_STATUS write failed, return (%d).", task_id, ret);
|
||||
|
@ -462,12 +462,12 @@ static int elf_process_tasks_regs(core_dump_elf_t *self, void* frame,
|
|||
// in this stage we can safely replace task's stack with IRQ's one
|
||||
// if task had corrupted stack it was replaced with fake one in HW dependent code called by elf_process_task_regdump()
|
||||
// in the "write data" stage registers from ISR's stack will be saved in PR_STATUS
|
||||
self->interrupted_task.stack_start = tasks[curr_task_index].stack_start;
|
||||
self->interrupted_task.stack_end = tasks[curr_task_index].stack_end;
|
||||
self->interrupted_task.stack_start = tasks[curr_task_index]->stack_start;
|
||||
self->interrupted_task.stack_end = tasks[curr_task_index]->stack_end;
|
||||
uint32_t isr_stk_end = esp_core_dump_get_isr_stack_end();
|
||||
ESP_COREDUMP_LOG_PROCESS("Add ISR stack %lu (%x - %x)", isr_stk_end - (uint32_t)frame, (uint32_t)frame, isr_stk_end);
|
||||
tasks[curr_task_index].stack_start = (uint32_t)frame;
|
||||
tasks[curr_task_index].stack_end = isr_stk_end;
|
||||
tasks[curr_task_index]->stack_start = (uint32_t)frame;
|
||||
tasks[curr_task_index]->stack_end = isr_stk_end;
|
||||
}
|
||||
|
||||
// actually we write current task's stack here which was replaced by ISR's
|
||||
|
@ -479,7 +479,7 @@ static int elf_process_tasks_regs(core_dump_elf_t *self, void* frame,
|
|||
}
|
||||
|
||||
static int elf_write_tasks_data(core_dump_elf_t *self, void* frame,
|
||||
core_dump_task_header_t* tasks,
|
||||
core_dump_task_header_t** tasks,
|
||||
uint32_t task_num)
|
||||
{
|
||||
int elf_len = 0;
|
||||
|
@ -496,11 +496,11 @@ static int elf_write_tasks_data(core_dump_elf_t *self, void* frame,
|
|||
// processes all task's stack data and writes segment data into partition
|
||||
// if flash configuration is set
|
||||
for (task_id = 0; task_id < task_num; task_id++) {
|
||||
ret = elf_process_task_tcb(self, &tasks[task_id]);
|
||||
ret = elf_process_task_tcb(self, tasks[task_id]);
|
||||
ELF_CHECK_ERR((ret > 0), ret,
|
||||
"Task #%d, TCB write failed, return (%d).", task_id, ret);
|
||||
elf_len += ret;
|
||||
ret = elf_process_task_stack(self, &tasks[task_id]);
|
||||
ret = elf_process_task_stack(self, tasks[task_id]);
|
||||
ELF_CHECK_ERR((ret != ELF_PROC_ERR_WRITE_FAIL), ELF_PROC_ERR_WRITE_FAIL,
|
||||
"Task #%d, stack write failed, return (%d).", task_id, ret);
|
||||
elf_len += ret;
|
||||
|
@ -546,7 +546,7 @@ static int elf_write_core_dump_info(core_dump_elf_t *self)
|
|||
}
|
||||
|
||||
static int esp_core_dump_do_write_elf_pass(core_dump_elf_t *self, void* frame,
|
||||
core_dump_task_header_t* tasks,
|
||||
core_dump_task_header_t** tasks,
|
||||
uint32_t task_num)
|
||||
{
|
||||
int tot_len = 0;
|
||||
|
@ -574,7 +574,7 @@ static int esp_core_dump_do_write_elf_pass(core_dump_elf_t *self, void* frame,
|
|||
esp_err_t esp_core_dump_write_elf(void *frame, core_dump_write_config_t *write_cfg)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
static core_dump_task_header_t tasks[CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM];
|
||||
static core_dump_task_header_t *tasks[CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM];
|
||||
static core_dump_elf_t self;
|
||||
core_dump_header_t dump_hdr;
|
||||
uint32_t tcb_sz = COREDUMP_TCB_SIZE, task_num;
|
||||
|
|
|
@ -275,13 +275,21 @@ inline bool esp_core_dump_tcb_addr_is_sane(uint32_t addr)
|
|||
return esp_core_dump_mem_seg_is_sane(addr, COREDUMP_TCB_SIZE);
|
||||
}
|
||||
|
||||
uint32_t esp_core_dump_get_tasks_snapshot(core_dump_task_header_t* const tasks,
|
||||
uint32_t esp_core_dump_get_tasks_snapshot(core_dump_task_header_t** const tasks,
|
||||
const uint32_t snapshot_size)
|
||||
{
|
||||
static TaskSnapshot_t s_tasks_snapshots[CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM];
|
||||
uint32_t tcb_sz; // unused
|
||||
uint32_t task_num = (uint32_t)uxTaskGetSnapshotAll((TaskSnapshot_t*)tasks,
|
||||
|
||||
/* implying that TaskSnapshot_t extends core_dump_task_header_t by adding extra fields */
|
||||
_Static_assert(sizeof(TaskSnapshot_t) >= sizeof(core_dump_task_header_t), "FreeRTOS task snapshot binary compatibility issue!");
|
||||
|
||||
uint32_t task_num = (uint32_t)uxTaskGetSnapshotAll(s_tasks_snapshots,
|
||||
(UBaseType_t)snapshot_size,
|
||||
(UBaseType_t*)&tcb_sz);
|
||||
for (uint32_t i = 0; i < task_num; i++) {
|
||||
tasks[i] = (core_dump_task_header_t *)&s_tasks_snapshots[i];
|
||||
}
|
||||
return task_num;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue