This commit is contained in:
Joseph Tang
2020-07-13 14:29:08 +08:00
committed by maojianxin
parent da66192023
commit 07ad7b9845
5 changed files with 97 additions and 16 deletions

View File

@@ -458,11 +458,13 @@ class ESPCoreDumpLoaderError(ESPCoreDumpError):
class ESPCoreDumpLoader(object):
"""Core dump loader base class
"""
ESP32_COREDUMP_VESION = 1
ESP32_COREDUMP_VESION = 2
ESP32_COREDUMP_HDR_FMT = '<4L'
ESP32_COREDUMP_HDR_SZ = struct.calcsize(ESP32_COREDUMP_HDR_FMT)
ESP32_COREDUMP_TSK_HDR_FMT = '<3L'
ESP32_COREDUMP_TSK_HDR_SZ = struct.calcsize(ESP32_COREDUMP_TSK_HDR_FMT)
ESP32_COREDUMP_LOG_HDR_FMT = '<2L'
ESP32_COREDUMP_LOG_HDR_SZ = struct.calcsize(ESP32_COREDUMP_LOG_HDR_FMT)
def __init__(self):
"""Base constructor for core dump loader
@@ -639,6 +641,13 @@ class ESPCoreDumpLoader(object):
note = Elf32NoteDesc("CORE", 1, prstatus.dump() + struct.pack("<%dL" % len(task_regs), *task_regs)).dump()
notes += note
# read log
data = self.read_data(core_off, self.ESP32_COREDUMP_LOG_HDR_SZ)
core_off += self.ESP32_COREDUMP_LOG_HDR_SZ
log_len, log_start = struct.unpack_from(self.ESP32_COREDUMP_LOG_HDR_FMT, data)
log_saved = self.read_data(core_off, log_len)
core_off += log_len
# add notes
try:
core_elf.add_program_segment(0, notes, ESPCoreDumpElfFile.PT_NOTE, 0)
@@ -662,7 +671,7 @@ class ESPCoreDumpLoader(object):
fce = os.fdopen(fhnd, 'wb')
core_elf.dump(fce)
fce.close()
return core_fname
return core_fname, log_saved
def read_data(self, off, sz):
"""Reads data from raw core dump got from flash or UART
@@ -900,7 +909,7 @@ def dbg_corefile(args):
rom_elf,rom_sym_cmd = load_aux_elf(args.rom_elf)
if not args.core:
loader = ESPCoreDumpFlashLoader(args.off, port=args.port)
core_fname = loader.create_corefile(args.save_core, rom_elf=rom_elf)
core_fname, log_saved = loader.create_corefile(args.save_core, rom_elf=rom_elf)
if not core_fname:
logging.error("Failed to create corefile!")
loader.cleanup()
@@ -909,7 +918,7 @@ def dbg_corefile(args):
core_fname = args.core
if args.core_format and args.core_format != 'elf':
loader = ESPCoreDumpFileLoader(core_fname, args.core_format == 'b64')
core_fname = loader.create_corefile(args.save_core, rom_elf=rom_elf)
core_fname, log_saved = loader.create_corefile(args.save_core, rom_elf=rom_elf)
if not core_fname:
logging.error("Failed to create corefile!")
loader.cleanup()
@@ -991,7 +1000,7 @@ def info_corefile(args):
rom_elf,rom_sym_cmd = load_aux_elf(args.rom_elf)
if not args.core:
loader = ESPCoreDumpFlashLoader(args.off, port=args.port)
core_fname = loader.create_corefile(args.save_core, rom_elf=rom_elf)
core_fname, log_saved = loader.create_corefile(args.save_core, rom_elf=rom_elf)
if not core_fname:
logging.error("Failed to create corefile!")
loader.cleanup()
@@ -1000,7 +1009,7 @@ def info_corefile(args):
core_fname = args.core
if args.core_format and args.core_format != 'elf':
loader = ESPCoreDumpFileLoader(core_fname, args.core_format == 'b64')
core_fname = loader.create_corefile(args.save_core, rom_elf=rom_elf)
core_fname, log_saved = loader.create_corefile(args.save_core, rom_elf=rom_elf)
if not core_fname:
logging.error("Failed to create corefile!")
loader.cleanup()
@@ -1089,6 +1098,10 @@ def info_corefile(args):
print(".coredump.%s 0x%x 0x%x %s" % (seg_name, cs.addr, len(cs.data), cs.attr_str()))
p = gdbmi_getinfo(p, handlers, "x/%dx 0x%x" % (old_div(len(cs.data),4), cs.addr))
if log_saved:
print("\n====================== CORE DUMP LOG CONTENTS ========================")
print(log_saved)
print("\n===================== ESP32 CORE DUMP END =====================")
print("===============================================================")

View File

@@ -46,7 +46,7 @@ void esp_core_dump_init();
* The structure of core dump data is described below in details.
* 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.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.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.
@@ -86,4 +86,9 @@ void esp_core_dump_to_uart(XtExcFrame *frame);
*/
esp_err_t esp_core_dump_image_get(size_t* out_addr, size_t *out_size);
typedef uint32_t (*log_dump_get_len_t)(void);
typedef int * (*log_dump_get_ptr_t)(void);
bool esp_log_dump_init(log_dump_get_len_t g_len, log_dump_get_ptr_t g_ptr);
#endif

View File

@@ -11,8 +11,8 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef ESP_CORE_DUMP_H_
#define ESP_CORE_DUMP_H_
#ifndef ESP_CORE_DUMP_PRIV_H_
#define ESP_CORE_DUMP_PRIV_H_
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@@ -33,7 +33,7 @@
#endif
#define COREDUMP_MAX_TASK_STACK_SIZE (64*1024)
#define COREDUMP_VERSION 1
#define COREDUMP_VERSION 2
typedef uint32_t core_dump_crc_t;
@@ -79,6 +79,12 @@ typedef struct _core_dump_task_header_t
uint32_t stack_end; // stack end address
} core_dump_task_header_t;
typedef struct _core_dump_log_header_t
{
uint32_t len; //bytes
int * start; //
} core_dump_log_header_t;
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
// Core dump flash init function
@@ -100,6 +106,8 @@ bool esp_core_dump_process_tcb(void *frame, core_dump_task_header_t *task_snapho
bool esp_core_dump_process_stack(core_dump_task_header_t* task_snaphort, uint32_t *length);
bool esp_core_dump_process_log(core_dump_log_header_t *log);
#endif
#endif

View File

@@ -34,18 +34,22 @@ static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_
core_dump_header_t hdr;
core_dump_task_header_t task_hdr;
} dump_data;
union {
uint32_t i32[128];
char str[512];
} iram_str;
task_num = esp_core_dump_get_tasks_snapshot(tasks, CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM, &tcb_sz);
ESP_COREDUMP_LOGI("Found tasks: (%d)!", task_num);
// Take TCB padding into account, actual TCB size will be stored in header
if (tcb_sz % sizeof(uint32_t))
tcb_sz_padded = (tcb_sz / sizeof(uint32_t) + 1) * sizeof(uint32_t);
else
tcb_sz_padded = tcb_sz;
// Verifies all tasks in the snapshot
for (i = 0; i < task_num; i++) {
for (i = 0; i < task_num; i++) {
task_is_valid = esp_core_dump_process_tcb(frame, &tasks[i], tcb_sz);
// Check if task tcb is corrupted
if (!task_is_valid) {
@@ -64,10 +68,16 @@ static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_
write_cfg->bad_tasks_num++;
}
}
core_dump_log_header_t logs = { 0 };
if (esp_core_dump_process_log(&logs) == true) {
data_len += (logs.len + sizeof(core_dump_log_header_t));
}
// Add core dump header size
data_len += sizeof(core_dump_header_t);
ESP_COREDUMP_LOG_PROCESS("Core dump len = %lu (%d %d)", data_len, task_num, write_cfg->bad_tasks_num);
// Prepare write
if (write_cfg->prepare) {
err = write_cfg->prepare(write_cfg->priv, &data_len);
@@ -129,6 +139,28 @@ static esp_err_t esp_core_dump_write_binary(void *frame, core_dump_write_config_
}
}
err = write_cfg->write(write_cfg->priv, (void*)&logs, sizeof(core_dump_log_header_t));
if (err != ESP_OK) {
ESP_COREDUMP_LOGE("Failed to write LOG Header (%d)!", err);
return err;
}
if (logs.len > 0 && logs.start != NULL) {
for (int i = 0; i < logs.len / 512; i++) {
for (int j = 0; j < 128; j++) {
if (i * 128 + j < logs.len / 4) {
iram_str.i32[j] = logs.start[i * 128+ j];
}
}
err = write_cfg->write(write_cfg->priv, (void*)iram_str.str, 512);
}
// err = write_cfg->write(write_cfg->priv, (void*)logs.start, logs.len);
// if (err != ESP_OK) {
// ESP_COREDUMP_LOGE("Failed to write LOG (%d)!", err);
// return err;
// }
}
// write end
if (write_cfg->end) {
err = write_cfg->end(write_cfg->priv);

View File

@@ -15,6 +15,7 @@
#include <stdbool.h>
#include "esp_panic.h"
#include "esp_core_dump_priv.h"
#include "esp_core_dump.h"
const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_port";
@@ -41,7 +42,7 @@ uint32_t esp_core_dump_get_tasks_snapshot(core_dump_task_header_t* const tasks,
bool esp_core_dump_process_tcb(void *frame, core_dump_task_header_t *task_snaphort, uint32_t tcb_sz)
{
XtExcFrame *exc_frame = (XtExcFrame*)frame;
if (!esp_tcb_addr_is_sane((uint32_t)task_snaphort->tcb_addr, tcb_sz)) {
ESP_COREDUMP_LOG_PROCESS("Bad TCB addr %x!", task_snaphort->tcb_addr);
return false;
@@ -74,7 +75,7 @@ bool esp_core_dump_process_tcb(void *frame, core_dump_task_header_t *task_snapho
}
bool esp_core_dump_process_stack(core_dump_task_header_t* task_snaphort, uint32_t *length)
{
{
uint32_t len = 0;
bool task_is_valid = false;
len = (uint32_t)task_snaphort->stack_end - (uint32_t)task_snaphort->stack_start;
@@ -99,5 +100,27 @@ bool esp_core_dump_process_stack(core_dump_task_header_t* task_snaphort, uint32_
}
return task_is_valid;
}
static log_dump_get_len_t get_len = NULL;
static log_dump_get_ptr_t get_ptr = NULL;
bool esp_log_dump_init(log_dump_get_len_t g_len, log_dump_get_ptr_t g_ptr)
{
get_len = g_len;
get_ptr = g_ptr;
return true;
}
bool esp_core_dump_process_log(core_dump_log_header_t *log)
{
if (get_len && get_ptr) {
log->len = get_len();
log->start = get_ptr();
return true;
} else {
log->len = 0;
log->start = NULL;
return false;
}
}
#endif