forked from espressif/esp-idf
log dump
This commit is contained in:
@@ -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("===============================================================")
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user