coredump: Fixes ESP-specific panic reasons handling

This commit is contained in:
Alexey Gerenkov 2020-06-08 19:32:35 +03:00
parent 2f74b4e023
commit 21091c6b0e
15 changed files with 73 additions and 51 deletions

View File

@ -1,6 +1,5 @@
idf_component_register(SRCS "panic.c" "system_api.c" "startup.c" idf_component_register(SRCS "panic.c" "system_api.c" "startup.c"
INCLUDE_DIRS include INCLUDE_DIRS include
PRIV_INCLUDE_DIRS private_include
PRIV_REQUIRES spi_flash app_update PRIV_REQUIRES spi_flash app_update
# requirements due to startup code # requirements due to startup code
nvs_flash pthread app_trace nvs_flash pthread app_trace

View File

@ -15,11 +15,13 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include "port/panic_funcs.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
extern bool g_panic_abort; extern bool g_panic_abort;
// Function to print longer amounts of information such as the details // Function to print longer amounts of information such as the details
@ -49,6 +51,7 @@ typedef struct {
panic_info_dump_fn_t state; // processor state, usually the contents of the registers panic_info_dump_fn_t state; // processor state, usually the contents of the registers
const void* addr; // instruction address that triggered the exception const void* addr; // instruction address that triggered the exception
const void* frame; // reference to the frame const void* frame; // reference to the frame
bool pseudo_excause; // flag indicating that exception cause has special meaning
} panic_info_t; } panic_info_t;
#define PANIC_INFO_DUMP(info, dump_fn) {if ((info)->dump_fn) (*(info)->dump_fn)((info->frame));} #define PANIC_INFO_DUMP(info, dump_fn) {if ((info)->dump_fn) (*(info)->dump_fn)((info->frame));}
@ -67,4 +70,8 @@ void panic_print_hex(int h);
#define panic_print_hex(h) #define panic_print_hex(h)
#endif #endif
void __attribute__((noreturn)) panic_abort(const char *details); void __attribute__((noreturn)) panic_abort(const char *details);
#ifdef __cplusplus
}
#endif

View File

@ -43,7 +43,7 @@
#include "hal/uart_hal.h" #include "hal/uart_hal.h"
#endif #endif
#include "panic_internal.h" #include "esp_private/panic_internal.h"
#include "port/panic_funcs.h" #include "port/panic_funcs.h"
#include "sdkconfig.h" #include "sdkconfig.h"
@ -204,7 +204,7 @@ void esp_panic_handler(panic_info_t *info)
* description - a short description regarding the exception that occured * description - a short description regarding the exception that occured
* details - more details about the exception * details - more details about the exception
* state - processor state like register contents, and backtrace * state - processor state like register contents, and backtrace
* elf_info - details about the image currently running * elf_info - details about the image currently running
* *
* NULL fields in panic_info_t are not printed. * NULL fields in panic_info_t are not printed.
* *
@ -302,10 +302,10 @@ void esp_panic_handler(panic_info_t *info)
disable_all_wdts(); disable_all_wdts();
s_dumping_core = true; s_dumping_core = true;
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH #if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
esp_core_dump_to_flash((XtExcFrame*) info->frame); esp_core_dump_to_flash(info);
#endif #endif
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART && !CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT #if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART && !CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT
esp_core_dump_to_uart((XtExcFrame*) info->frame); esp_core_dump_to_uart(info);
#endif #endif
s_dumping_core = false; s_dumping_core = false;
reconfigure_all_wdts(); reconfigure_all_wdts();
@ -332,7 +332,7 @@ void esp_panic_handler(panic_info_t *info)
break; // do not touch the previously set reset reason hint break; // do not touch the previously set reset reason hint
} }
} }
panic_print_str("Rebooting...\r\n"); panic_print_str("Rebooting...\r\n");
panic_restart(); panic_restart();
#else #else

View File

@ -46,7 +46,7 @@
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#endif #endif
#include "panic_internal.h" #include "esp_private/panic_internal.h"
extern int _invalid_pc_placeholder; extern int _invalid_pc_placeholder;
@ -383,6 +383,7 @@ static void frame_to_panic_info(XtExcFrame *frame, panic_info_t *info, bool pseu
info->exception = PANIC_EXCEPTION_FAULT; info->exception = PANIC_EXCEPTION_FAULT;
info->details = NULL; info->details = NULL;
info->pseudo_excause = pseudo_excause;
if (pseudo_excause) { if (pseudo_excause) {
if (frame->exccause == PANIC_RSN_INTWDT_CPU0) { if (frame->exccause == PANIC_RSN_INTWDT_CPU0) {
info->core = 0; info->core = 0;

View File

@ -6,7 +6,7 @@
#include "soc/cpu.h" #include "soc/cpu.h"
#include "soc/rtc.h" #include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include "panic_internal.h" #include "esp_private/panic_internal.h"
#include "esp_rom_uart.h" #include "esp_rom_uart.h"
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/memprot.h" #include "esp32s2/memprot.h"

View File

@ -53,6 +53,7 @@ else:
CLOSE_FDS = True CLOSE_FDS = True
INVALID_CAUSE_VALUE = 0xFFFF INVALID_CAUSE_VALUE = 0xFFFF
XCHAL_EXCCAUSE_NUM = 64
# Exception cause dictionary to get translation of exccause register # Exception cause dictionary to get translation of exccause register
# From 4.4.1.5 table 4-64 Exception Causes of Xtensa # From 4.4.1.5 table 4-64 Exception Causes of Xtensa
@ -88,7 +89,17 @@ xtensa_exception_cause_dict = {
37: ("Coprocessor5Disabled", "Coprocessor 5 instruction when cp5 disabled"), 37: ("Coprocessor5Disabled", "Coprocessor 5 instruction when cp5 disabled"),
38: ("Coprocessor6Disabled", "Coprocessor 6 instruction when cp6 disabled"), 38: ("Coprocessor6Disabled", "Coprocessor 6 instruction when cp6 disabled"),
39: ("Coprocessor7Disabled", "Coprocessor 7 instruction when cp7 disabled"), 39: ("Coprocessor7Disabled", "Coprocessor 7 instruction when cp7 disabled"),
INVALID_CAUSE_VALUE: ("InvalidCauseRegister", "Invalid EXCCAUSE register value or current task is broken and was skipped")} INVALID_CAUSE_VALUE: ("InvalidCauseRegister", "Invalid EXCCAUSE register value or current task is broken and was skipped"),
# ESP panic pseudo reasons
XCHAL_EXCCAUSE_NUM + 0: ("UnknownException", "Unknown exception"),
XCHAL_EXCCAUSE_NUM + 1: ("DebugException", "Unhandled debug exception"),
XCHAL_EXCCAUSE_NUM + 2: ("DoubleException", "Double exception"),
XCHAL_EXCCAUSE_NUM + 3: ("KernelException", "Unhandled kernel exception"),
XCHAL_EXCCAUSE_NUM + 4: ("CoprocessorException", "Coprocessor exception"),
XCHAL_EXCCAUSE_NUM + 5: ("InterruptWDTTimoutCPU0", "Interrupt wdt timeout on CPU0"),
XCHAL_EXCCAUSE_NUM + 6: ("InterruptWDTTimoutCPU1", "Interrupt wdt timeout on CPU1"),
XCHAL_EXCCAUSE_NUM + 7: ("CacheError", "Cache disabled but cached memory region accessed"),
}
class ESPCoreDumpError(RuntimeError): class ESPCoreDumpError(RuntimeError):

View File

@ -17,6 +17,7 @@
#include <stddef.h> #include <stddef.h>
#include "esp_err.h" #include "esp_err.h"
#include "freertos/xtensa_context.h" #include "freertos/xtensa_context.h"
#include "esp_private/panic_internal.h"
/**************************************************************************************/ /**************************************************************************************/
/******************************** EXCEPTION MODE API **********************************/ /******************************** EXCEPTION MODE API **********************************/
@ -46,7 +47,7 @@ void esp_core_dump_init(void);
* The structure of core dump data is described below in details. * The structure of core dump data is described below in details.
* 1) Core dump starts with header: * 1) Core dump starts with header:
* 1.1) TOTAL_LEN is total length of core dump data in flash including CRC. Size is 4 bytes. * 1.1) TOTAL_LEN is total length of core dump data in flash including CRC. Size is 4 bytes.
* 1.2) VERSION field keeps 4 byte version of core dump. * 1.2) VERSION field keeps 4 byte version of core dump.
* 1.2) TASKS_NUM is the number of tasks for which data are stored. Size is 4 bytes. * 1.2) TASKS_NUM is the number of tasks for which data are stored. Size is 4 bytes.
* 1.3) TCB_SIZE is the size of task's TCB structure. Size is 4 bytes. * 1.3) TCB_SIZE is the size of task's TCB structure. Size is 4 bytes.
* 2) Core dump header is followed by the data for every task in the system. * 2) Core dump header is followed by the data for every task in the system.
@ -58,7 +59,7 @@ void esp_core_dump_init(void);
* 4) Task's stack is placed after TCB data. Size is (STACK_END - STACK_TOP) bytes. * 4) Task's stack is placed after TCB data. Size is (STACK_END - STACK_TOP) bytes.
* 5) CRC is placed at the end of the data. * 5) CRC is placed at the end of the data.
*/ */
void esp_core_dump_to_flash(XtExcFrame *frame); void esp_core_dump_to_flash(panic_info_t *info);
/** /**
* @brief Print base64-encoded core dump to UART. * @brief Print base64-encoded core dump to UART.
@ -68,7 +69,7 @@ void esp_core_dump_to_flash(XtExcFrame *frame);
* 2) Since CRC is omitted TOTAL_LEN does not include its size. * 2) Since CRC is omitted TOTAL_LEN does not include its size.
* 3) Printed base64 data are surrounded with special messages to help user recognize the start and end of actual data. * 3) Printed base64 data are surrounded with special messages to help user recognize the start and end of actual data.
*/ */
void esp_core_dump_to_uart(XtExcFrame *frame); void esp_core_dump_to_uart(panic_info_t *info);
/**************************************************************************************/ /**************************************************************************************/
/*********************************** USER MODE API ************************************/ /*********************************** USER MODE API ************************************/

View File

@ -16,6 +16,6 @@
#include "esp_core_dump_priv.h" #include "esp_core_dump_priv.h"
esp_err_t esp_core_dump_write_elf(void *frame, core_dump_write_config_t *write_cfg); esp_err_t esp_core_dump_write_elf(panic_info_t *info, core_dump_write_config_t *write_cfg);
#endif #endif

View File

@ -56,7 +56,7 @@ bool esp_core_dump_tcb_addr_is_sane(uint32_t addr);
bool esp_core_dump_task_stack_end_is_sane(uint32_t sp); bool esp_core_dump_task_stack_end_is_sane(uint32_t sp);
bool esp_core_dump_mem_seg_is_sane(uint32_t addr, uint32_t sz); bool esp_core_dump_mem_seg_is_sane(uint32_t addr, uint32_t sz);
void *esp_core_dump_get_current_task_handle(void); void *esp_core_dump_get_current_task_handle(void);
bool esp_core_dump_check_task(void *frame, core_dump_task_header_t *task_snaphort, bool* is_current, bool* stack_is_valid); bool esp_core_dump_check_task(panic_info_t *info, core_dump_task_header_t *task_snaphort, bool* is_current, bool* stack_is_valid);
bool esp_core_dump_check_stack(uint32_t stack_start, uint32_t stack_end); bool esp_core_dump_check_stack(uint32_t stack_start, uint32_t stack_end);
uint32_t esp_core_dump_get_stack(core_dump_task_header_t* task_snapshot, uint32_t* stk_base, uint32_t* stk_len); uint32_t esp_core_dump_get_stack(core_dump_task_header_t* task_snapshot, uint32_t* stk_base, uint32_t* stk_len);

View File

@ -22,6 +22,7 @@ extern "C" {
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_log.h" #include "esp_log.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_private/panic_internal.h"
#if CONFIG_ESP32_COREDUMP_CHECKSUM_SHA256 #if CONFIG_ESP32_COREDUMP_CHECKSUM_SHA256
// TODO: move this to portable part of the code // TODO: move this to portable part of the code
#include "mbedtls/sha256.h" #include "mbedtls/sha256.h"
@ -137,7 +138,7 @@ typedef struct _core_dump_mem_seg_header_t
void esp_core_dump_flash_init(void); void esp_core_dump_flash_init(void);
// Common core dump write function // Common core dump write function
void esp_core_dump_write(void *frame, core_dump_write_config_t *write_cfg); void esp_core_dump_write(panic_info_t *info, core_dump_write_config_t *write_cfg);
#include "esp_core_dump_port.h" #include "esp_core_dump_port.h"

View File

@ -14,7 +14,6 @@
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_core_dump_priv.h"
#include "core_dump_elf.h" #include "core_dump_elf.h"
const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_common"; const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_common";
@ -100,7 +99,7 @@ static esp_err_t esp_core_dump_save_mem_segment(core_dump_write_config_t* write_
return ESP_OK; return ESP_OK;
} }
static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_t *write_cfg) static esp_err_t esp_core_dump_write_binary(panic_info_t *info, core_dump_write_config_t *write_cfg)
{ {
esp_err_t err; 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];
@ -117,7 +116,7 @@ static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_
for (task_id = 0; task_id < task_num; task_id++) { for (task_id = 0; task_id < task_num; task_id++) {
bool is_current_task = false, stack_is_valid = false; 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(info, tasks[task_id], &is_current_task, &stack_is_valid);
// Check if task tcb or stack is corrupted // Check if task tcb or stack is corrupted
if (!tcb_is_valid || !stack_is_valid) { if (!tcb_is_valid || !stack_is_valid) {
// If tcb or stack for task is corrupted count task as broken // If tcb or stack for task is corrupted count task as broken
@ -142,7 +141,7 @@ static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_
interrupted_task_stack.size = esp_core_dump_get_memory_len(tasks[curr_task_index]->stack_start, tasks[curr_task_index]->stack_end); interrupted_task_stack.size = esp_core_dump_get_memory_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 // 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); data_len += sizeof(core_dump_mem_seg_header_t);
tasks[curr_task_index]->stack_start = (uint32_t)frame; tasks[curr_task_index]->stack_start = (uint32_t)info->frame;
tasks[curr_task_index]->stack_end = esp_core_dump_get_isr_stack_end(); 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); 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 // take into account size of the ISR stack
@ -199,7 +198,7 @@ static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_
hdr.version = COREDUMP_VERSION; hdr.version = COREDUMP_VERSION;
hdr.tasks_num = task_num; // save all the tasks in snapshot even broken hdr.tasks_num = task_num; // save all the tasks in snapshot even broken
hdr.mem_segs_num = 0; hdr.mem_segs_num = 0;
if (xPortInterruptedFromISRContext()) { if (esp_core_dump_in_isr_context()) {
hdr.mem_segs_num++; // stack of interrupted task hdr.mem_segs_num++; // stack of interrupted task
} }
hdr.mem_segs_num += esp_core_dump_get_user_ram_segments(); // stack of user mapped memory hdr.mem_segs_num += esp_core_dump_get_user_ram_segments(); // stack of user mapped memory
@ -231,7 +230,7 @@ static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_
return err; return err;
} }
} }
if (xPortInterruptedFromISRContext()) { if (esp_core_dump_in_isr_context()) {
err = esp_core_dump_save_mem_segment(write_cfg, &interrupted_task_stack); err = esp_core_dump_save_mem_segment(write_cfg, &interrupted_task_stack);
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_COREDUMP_LOGE("Failed to save interrupted task stack, error=%d!", err); ESP_COREDUMP_LOGE("Failed to save interrupted task stack, error=%d!", err);
@ -279,16 +278,16 @@ static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_
#endif #endif
inline void esp_core_dump_write(void *frame, core_dump_write_config_t *write_cfg) inline void esp_core_dump_write(panic_info_t *info, core_dump_write_config_t *write_cfg)
{ {
esp_core_dump_setup_stack(); esp_core_dump_setup_stack();
#ifndef CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE #ifndef CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE
esp_err_t err = ESP_ERR_NOT_SUPPORTED; esp_err_t err = ESP_ERR_NOT_SUPPORTED;
#if CONFIG_ESP32_COREDUMP_DATA_FORMAT_BIN #if CONFIG_ESP32_COREDUMP_DATA_FORMAT_BIN
err = esp_core_dump_write_binary(frame, write_cfg); err = esp_core_dump_write_binary(info, write_cfg);
#elif CONFIG_ESP32_COREDUMP_DATA_FORMAT_ELF #elif CONFIG_ESP32_COREDUMP_DATA_FORMAT_ELF
err = esp_core_dump_write_elf(frame, write_cfg); err = esp_core_dump_write_elf(info, write_cfg);
#endif #endif
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_COREDUMP_LOGE("Core dump write binary failed with error=%d", err); ESP_COREDUMP_LOGE("Core dump write binary failed with error=%d", err);

View File

@ -325,7 +325,7 @@ static int elf_get_current_task_index(core_dump_task_header_t** tasks,
return curr_task_index; return curr_task_index;
} }
static int elf_process_task_regdump(core_dump_elf_t *self, void *frame, core_dump_task_header_t *task) static int elf_process_task_regdump(core_dump_elf_t *self, panic_info_t *info, core_dump_task_header_t *task)
{ {
bool task_is_valid = false; bool task_is_valid = false;
bool task_is_current = false; bool task_is_current = false;
@ -334,7 +334,7 @@ static int elf_process_task_regdump(core_dump_elf_t *self, void *frame, core_dum
if (self->elf_stage == ELF_STAGE_CALC_SPACE) { if (self->elf_stage == ELF_STAGE_CALC_SPACE) {
// Check if task tcb is corrupted (do not update the header, save as is) // Check if task tcb is corrupted (do not update the header, save as is)
task_is_valid = esp_core_dump_check_task(frame, task, &task_is_current, NULL); task_is_valid = esp_core_dump_check_task(info, task, &task_is_current, NULL);
if (!task_is_valid) { if (!task_is_valid) {
if (task_is_current) { if (task_is_current) {
ESP_COREDUMP_LOG_PROCESS("Task has incorrect (TCB:%x)!", ESP_COREDUMP_LOG_PROCESS("Task has incorrect (TCB:%x)!",
@ -417,7 +417,7 @@ static int elf_process_note_segment(core_dump_elf_t *self, int notes_size)
return (int)notes_size; return (int)notes_size;
} }
static int elf_process_tasks_regs(core_dump_elf_t *self, void* frame, static int elf_process_tasks_regs(core_dump_elf_t *self, panic_info_t *info,
core_dump_task_header_t** tasks, core_dump_task_header_t** tasks,
uint32_t task_num) uint32_t task_num)
{ {
@ -430,7 +430,7 @@ static int elf_process_tasks_regs(core_dump_elf_t *self, void* frame,
} }
// place current task dump first // place current task dump first
int ret = elf_process_task_regdump(self, frame, tasks[curr_task_index]); int ret = elf_process_task_regdump(self, info, tasks[curr_task_index]);
if (self->elf_stage == ELF_STAGE_PLACE_HEADERS) { if (self->elf_stage == ELF_STAGE_PLACE_HEADERS) {
// when writing segments headers this function writes nothing // 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); ELF_CHECK_ERR((ret >= 0), ret, "Task #%d, PR_STATUS write failed, return (%d).", curr_task_index, ret);
@ -446,7 +446,7 @@ static int elf_process_tasks_regs(core_dump_elf_t *self, void* frame,
if (task_id == curr_task_index) { if (task_id == curr_task_index) {
continue; // skip current task (already processed) continue; // skip current task (already processed)
} }
ret = elf_process_task_regdump(self, frame, tasks[task_id]); ret = elf_process_task_regdump(self, info, tasks[task_id]);
if (self->elf_stage == ELF_STAGE_PLACE_HEADERS) { if (self->elf_stage == ELF_STAGE_PLACE_HEADERS) {
// when writing segments headers this function writes nothing // 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); ELF_CHECK_ERR((ret >= 0), ret, "Task #%d, PR_STATUS write failed, return (%d).", task_id, ret);
@ -467,8 +467,8 @@ static int elf_process_tasks_regs(core_dump_elf_t *self, void* frame,
self->interrupted_task.stack_start = tasks[curr_task_index]->stack_start; 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_end = tasks[curr_task_index]->stack_end;
uint32_t isr_stk_end = esp_core_dump_get_isr_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); ESP_COREDUMP_LOG_PROCESS("Add ISR stack %lu (%x - %x)", isr_stk_end - (uint32_t)info->frame, (uint32_t)info->frame, isr_stk_end);
tasks[curr_task_index]->stack_start = (uint32_t)frame; tasks[curr_task_index]->stack_start = (uint32_t)info->frame;
tasks[curr_task_index]->stack_end = isr_stk_end; tasks[curr_task_index]->stack_end = isr_stk_end;
} }
@ -480,7 +480,7 @@ static int elf_process_tasks_regs(core_dump_elf_t *self, void* frame,
return ret; return ret;
} }
static int elf_write_tasks_data(core_dump_elf_t *self, void* frame, static int elf_write_tasks_data(core_dump_elf_t *self, panic_info_t *info,
core_dump_task_header_t** tasks, core_dump_task_header_t** tasks,
uint32_t task_num) uint32_t task_num)
{ {
@ -488,9 +488,9 @@ static int elf_write_tasks_data(core_dump_elf_t *self, void* frame,
int task_id; int task_id;
int ret = ELF_PROC_ERR_OTHER; int ret = ELF_PROC_ERR_OTHER;
ELF_CHECK_ERR((frame && tasks), ELF_PROC_ERR_OTHER, "Invalid input data."); ELF_CHECK_ERR((info && tasks), ELF_PROC_ERR_OTHER, "Invalid input data.");
ret = elf_process_tasks_regs(self, frame, tasks, task_num); ret = elf_process_tasks_regs(self, info, tasks, task_num);
ELF_CHECK_ERR((ret > 0), ret, "Tasks regs addition failed, return (%d).", ret); ELF_CHECK_ERR((ret > 0), ret, "Tasks regs addition failed, return (%d).", ret);
elf_len += ret; elf_len += ret;
self->bad_tasks_num = 0; // reset bad task counter self->bad_tasks_num = 0; // reset bad task counter
@ -572,7 +572,7 @@ static int elf_write_core_dump_info(core_dump_elf_t *self)
return ret; return ret;
} }
static int esp_core_dump_do_write_elf_pass(core_dump_elf_t *self, void* frame, static int esp_core_dump_do_write_elf_pass(core_dump_elf_t *self, panic_info_t *info,
core_dump_task_header_t** tasks, core_dump_task_header_t** tasks,
uint32_t task_num) uint32_t task_num)
{ {
@ -586,7 +586,7 @@ static int esp_core_dump_do_write_elf_pass(core_dump_elf_t *self, void* frame,
} }
tot_len += data_sz; tot_len += data_sz;
// Calculate whole size include headers for all tasks and main elf header // Calculate whole size include headers for all tasks and main elf header
data_sz = elf_write_tasks_data(self, frame, tasks, task_num); data_sz = elf_write_tasks_data(self, info, tasks, task_num);
ELF_CHECK_ERR((data_sz > 0), data_sz, "ELF Size writing error, returned (%d).", data_sz); ELF_CHECK_ERR((data_sz > 0), data_sz, "ELF Size writing error, returned (%d).", data_sz);
tot_len += data_sz; tot_len += data_sz;
@ -604,7 +604,7 @@ static int esp_core_dump_do_write_elf_pass(core_dump_elf_t *self, void* frame,
return tot_len; return tot_len;
} }
esp_err_t esp_core_dump_write_elf(void *frame, core_dump_write_config_t *write_cfg) esp_err_t esp_core_dump_write_elf(panic_info_t *info, core_dump_write_config_t *write_cfg)
{ {
esp_err_t err = ESP_OK; 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];
@ -614,7 +614,7 @@ esp_err_t esp_core_dump_write_elf(void *frame, core_dump_write_config_t *write_c
int tot_len = sizeof(dump_hdr); int tot_len = sizeof(dump_hdr);
int write_len = sizeof(dump_hdr); int write_len = sizeof(dump_hdr);
ELF_CHECK_ERR((frame && write_cfg), ESP_ERR_INVALID_ARG, "Invalid input data."); ELF_CHECK_ERR((info && write_cfg), ESP_ERR_INVALID_ARG, "Invalid input data.");
task_num = esp_core_dump_get_tasks_snapshot(tasks, CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM); task_num = esp_core_dump_get_tasks_snapshot(tasks, CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM);
ESP_COREDUMP_LOGI("Found tasks: %d", task_num); ESP_COREDUMP_LOGI("Found tasks: %d", task_num);
@ -625,7 +625,7 @@ esp_err_t esp_core_dump_write_elf(void *frame, core_dump_write_config_t *write_c
// On first pass (do not write actual data), but calculate data length needed to allocate memory // On first pass (do not write actual data), but calculate data length needed to allocate memory
self.elf_stage = ELF_STAGE_CALC_SPACE; self.elf_stage = ELF_STAGE_CALC_SPACE;
ESP_COREDUMP_LOG_PROCESS("================= Calc data size ==============="); ESP_COREDUMP_LOG_PROCESS("================= Calc data size ===============");
int ret = esp_core_dump_do_write_elf_pass(&self, frame, tasks, task_num); int ret = esp_core_dump_do_write_elf_pass(&self, info, tasks, task_num);
if (ret < 0) return ret; if (ret < 0) return ret;
tot_len += ret; tot_len += ret;
ESP_COREDUMP_LOG_PROCESS("Core dump tot_len=%lu, tasks processed: %d, broken tasks: %d", ESP_COREDUMP_LOG_PROCESS("Core dump tot_len=%lu, tasks processed: %d, broken tasks: %d",
@ -671,7 +671,7 @@ esp_err_t esp_core_dump_write_elf(void *frame, core_dump_write_config_t *write_c
self.elf_stage = ELF_STAGE_PLACE_HEADERS; self.elf_stage = ELF_STAGE_PLACE_HEADERS;
// set initial offset to elf segments data area // set initial offset to elf segments data area
self.elf_next_data_offset = sizeof(elfhdr) + ELF_SEG_HEADERS_COUNT(&self, task_num) * sizeof(elf_phdr); self.elf_next_data_offset = sizeof(elfhdr) + ELF_SEG_HEADERS_COUNT(&self, task_num) * sizeof(elf_phdr);
ret = esp_core_dump_do_write_elf_pass(&self, frame, tasks, task_num); ret = esp_core_dump_do_write_elf_pass(&self, info, tasks, task_num);
if (ret < 0) return ret; if (ret < 0) return ret;
write_len += ret; write_len += ret;
ESP_COREDUMP_LOG_PROCESS("============== Headers size = %d bytes ============", write_len); ESP_COREDUMP_LOG_PROCESS("============== Headers size = %d bytes ============", write_len);
@ -679,7 +679,7 @@ esp_err_t esp_core_dump_write_elf(void *frame, core_dump_write_config_t *write_c
self.elf_stage = ELF_STAGE_PLACE_DATA; self.elf_stage = ELF_STAGE_PLACE_DATA;
// set initial offset to elf segments data area, this is not necessary in this stage, just for pretty debug output // set initial offset to elf segments data area, this is not necessary in this stage, just for pretty debug output
self.elf_next_data_offset = sizeof(elfhdr) + ELF_SEG_HEADERS_COUNT(&self, task_num) * sizeof(elf_phdr); self.elf_next_data_offset = sizeof(elfhdr) + ELF_SEG_HEADERS_COUNT(&self, task_num) * sizeof(elf_phdr);
ret = esp_core_dump_do_write_elf_pass(&self, frame, tasks, task_num); ret = esp_core_dump_do_write_elf_pass(&self, info, tasks, task_num);
if (ret < 0) return ret; if (ret < 0) return ret;
write_len += ret; write_len += ret;
ESP_COREDUMP_LOG_PROCESS("=========== Data written size = %d bytes ==========", write_len); ESP_COREDUMP_LOG_PROCESS("=========== Data written size = %d bytes ==========", write_len);

View File

@ -222,7 +222,7 @@ static esp_err_t esp_core_dump_flash_write_end(void *priv)
return err; return err;
} }
void esp_core_dump_to_flash(void *frame) void esp_core_dump_to_flash(panic_info_t *info)
{ {
static core_dump_write_config_t wr_cfg; static core_dump_write_config_t wr_cfg;
static core_dump_write_data_t wr_data; static core_dump_write_data_t wr_data;
@ -250,7 +250,7 @@ void esp_core_dump_to_flash(void *frame)
wr_cfg.priv = &wr_data; wr_cfg.priv = &wr_data;
ESP_COREDUMP_LOGI("Save core dump to flash..."); ESP_COREDUMP_LOGI("Save core dump to flash...");
esp_core_dump_write(frame, &wr_cfg); esp_core_dump_write(info, &wr_cfg);
ESP_COREDUMP_LOGI("Core dump has been saved to flash."); ESP_COREDUMP_LOGI("Core dump has been saved to flash.");
} }

View File

@ -454,12 +454,12 @@ inline void* esp_core_dump_get_current_task_handle()
return (void*)xTaskGetCurrentTaskHandleForCPU(xPortGetCoreID()); return (void*)xTaskGetCurrentTaskHandleForCPU(xPortGetCoreID());
} }
bool esp_core_dump_check_task(void *frame, bool esp_core_dump_check_task(panic_info_t *info,
core_dump_task_header_t *task, core_dump_task_header_t *task,
bool* is_current, bool* is_current,
bool* stack_is_valid) bool* stack_is_valid)
{ {
XtExcFrame *exc_frame = frame; XtExcFrame *exc_frame = (XtExcFrame *)info->frame;
bool is_curr_task = false; bool is_curr_task = false;
bool stack_is_sane = false; bool stack_is_sane = false;
uint32_t stk_size = 0; uint32_t stk_size = 0;
@ -477,6 +477,9 @@ bool esp_core_dump_check_task(void *frame,
task->stack_start = (uint32_t)exc_frame; task->stack_start = (uint32_t)exc_frame;
} }
exc_frame->exit = COREDUMP_CURR_TASK_MARKER; exc_frame->exit = COREDUMP_CURR_TASK_MARKER;
if (info->pseudo_excause) {
exc_frame->exccause += XCHAL_EXCCAUSE_NUM;
}
s_extra_info.crashed_task_tcb = (uint32_t)task->tcb_addr; s_extra_info.crashed_task_tcb = (uint32_t)task->tcb_addr;
} }

View File

@ -128,7 +128,7 @@ static int esp_core_dump_uart_get_char(void) {
return i; return i;
} }
void esp_core_dump_to_uart(XtExcFrame *frame) void esp_core_dump_to_uart(panic_info_t *info)
{ {
core_dump_write_config_t wr_cfg; core_dump_write_config_t wr_cfg;
core_dump_write_data_t wr_data; core_dump_write_data_t wr_data;
@ -161,7 +161,7 @@ void esp_core_dump_to_uart(XtExcFrame *frame)
ch = esp_core_dump_uart_get_char(); ch = esp_core_dump_uart_get_char();
} }
ESP_COREDUMP_LOGI("Print core dump to uart..."); ESP_COREDUMP_LOGI("Print core dump to uart...");
esp_core_dump_write((void*)frame, &wr_cfg); esp_core_dump_write(info, &wr_cfg);
ESP_COREDUMP_LOGI("Core dump has been written to uart."); ESP_COREDUMP_LOGI("Core dump has been written to uart.");
} }