Debug:coredump
1. 在CPU触发异常时,会把当前的内存中的数据dump到串口中,用户可以保存到日志为coredump.log,coredump格式如下。
-+-+-+- BFLB COREDUMP v0.0.1 +-+-+-+
------ DATA BEGIN 62xxxxxx@00000400@predefined ------
...
...
------ END R6yo3A== ------
2. 将这些数据导入到gdb server中,可以使用gdb来对这些数据进行解析,获得异常发生时的一些状态。比如哪个进程发生了异常,别的进程的状态是什么样子的。
./tools/byai/coredump.py命令会创建一个gdb server,创建虚拟的32bit内存空间,把elf文件与coredump文件加载到内存空间中,并自动打开gdb client连接。
usage: coredump.py [-h] [-x GDB_INIT] log_file elf_file
3. 如下的例子,可见coredump.py传入coredump.log与elf后,这可打印当前运行的任务,可以使用bouffalo_sdk.gdb内置的一些函数来对某个TCB进行backtrace。
:~/bouffalo_sdk$ ./tools/byai/coredump.py coredump_20260604b/coredump.log coredump_20260604b/image_transmission_bl616cl.elf
Auto-selected free port: 50659
Starting local GDB server on port 50659...
GDB server ready. Connect from GDB using:
(gdb) file coredump_20260604b/image_transmission_bl616cl.elf
(gdb) target remote localhost:50659
(gdb) source /home/wyb/repo/new4/bouffalo_sdk/tools/bouffalo_sdk.gdb
Auto-starting GDB client: riscv64-unknown-elf-gdb -ex file coredump_20260604b/image_transmission_bl616cl.elf -ex target remote localhost:50659 -x /home/wyb/repo/new4/bouffalo_sdk/tools/bouffalo_sdk.gdb
...
...
Reading symbols from coredump_20260604b/image_transmission_bl616cl.elf...
Remote debugging using localhost:50659
Loading ELF PT_LOAD data from: coredump_20260604b/image_transmission_bl616cl.elf
Loaded 6 ELF PT_LOAD segments, 623074 bytes at LMA
Initialized 6 ELF PT_LOAD segments at LMA from coredump_20260604b/image_transmission_bl616cl.elf
Parsing coredump from: coredump_20260604b/coredump.log
Found 1 COREDUMP sections, processing the last one
Parsed 4460 memory blocks
Loaded 4460 coredump memory blocks at VMA from coredump_20260604b/ReceivedTofile-COM5-2026_6_4_11-43-48.log
Target local: Client connected from 127.0.0.1:38348
0x00000000 in ?? ()
(gdb) p pxCurrentTCB
$1 = (TCB_t * volatile) 0x880f49d4
(gdb) task_dump 0x880f49d4
$2 = {pxTopOfStack = 0x60fd83d4, xStateListItem = {xItemValue = 0, pxNext = 0x60fd0084 <pxReadyTasksLists+108>, pxPrevious = 0x60fd0084 <pxReadyTasksLists+108>, pvOwner = 0x880f49d4, pvContainer = 0x60fd007c <pxReadyTasksLists+100>}, xEventListItem = {xItemValue = 27, pxNext = 0x880f4974, pxPrevious = 0x880f4974, pvOwner = 0x880f49d4, pvContainer = 0x0}, uxPriority = 5, pxStack = 0x60fd7560, pcTaskName = "shell_task\000\000\000\000\000", pxEndOfStack = 0x60fd8550, uxCriticalNesting = 0, uxTCBNumber = 4, uxTaskNumber = 0, uxBasePriority = 5, uxMutexesHeld = 0, pxTaskTag = 0x0, pvThreadLocalStoragePointers = {0x0}, pvThreadLocalStoragePointersDelCallback = {0x0}, ulRunTimeCounter = 65, ulNotifiedValue = {0, 0, 0, 0}, ucNotifyState = "\000\000\000", ucStaticallyAllocated = 0 '\000', ucDelayAborted = 0 '\000', iTaskErrno = 0}
FPU is CLEAN (FS=0x2) - using offset +31 words
mstatus: 0x5880
stack_top: 0x60fd83d4
#0 0x800729b6 in shell_memtrace (argc=<optimized out>, argv=<optimized out>) at ./components/shell/shell.c:93
#1 0x80072f62 in shell_exec_cmd (retp=<optimized out>, length=<optimized out>, cmd=<optimized out>) at ./components/shell/shell.c:533
#2 shell_exec (cmd=0x60fd3916 <_shell+606> "memtrace", length=21) at ./components/shell/shell.c:601
#3 0x80073136 in shell_handler (data=<optimized out>) at ./components/shell/shell.c:794
#4 0x80073944 in shell_task (pvParameters=<optimized out>) at ./components/shell/shell_freertos.c:135
#5 0x00000000 in ?? ()
Backtrace stopped: frame did not save the PC
(gdb) task_list_wait
tcb: 0x880f7298 mstatus: 0x5880 [FPU_CLEAN] name: xxxx
tcb: 0x880f4d20 mstatus: 0x5880 [FPU_CLEAN] name: tcpip_thread
tcb: 0x60fccc08 mstatus: 0x5880 [FPU_CLEAN] name: display_thread
tcb: 0x60fc8ae0 mstatus: 0x5880 [FPU_CLEAN] name: MainTask
tcb: 0x880f73c4 mstatus: 0x5880 [FPU_CLEAN] name: xxxx
tcb: 0x880f6850 mstatus: 0x5880 [FPU_CLEAN] name: xxxx
tcb: 0x880f6e28 mstatus: 0x80007880 [FPU_CLEAN] name: xxxx
tcb: 0x880f5124 mstatus: 0x80007880 [FPU_CLEAN] name: xxxx
tcb: 0x60fd18c8 mstatus: 0x5880 [FPU_CLEAN] name: Tmr Svc
tcb: 0x880f4aec mstatus: 0x5800 [FPU_CLEAN] name: wifi fw
(gdb) task_list_ready
tcb: 0x60fd1840 mstatus: 0x5880 [FPU_CLEAN] name: IDLE
tcb: 0x880f49d4 mstatus: 0x5880 [FPU_CLEAN] name: shell_task
Q:如何退出
A:按CTRL+D或者CTRL+C可以退出coredump.py
Q:日志的格式,多个COREDUMP在同一个日志会怎么样
A:日志支持UTF8,UTF32LE、BE,CRLF/LF,基本上默认的格式不需要转换都支持,当日志中有多个保存的coredump时,会自动选择最后一个。
Q:有时候会有如下打印,是什么意思
crc check addr: 88021400, length: 00000400, end_crc: eebd05e9, crc: 8981de62
crc check addr: 8806e000, length: 00000400, end_crc: 2f25c5c9, crc: a9c6462e
crc check addr: 880ac800, length: 00000400, end_crc: 28c04c90, crc: 79f28ecb
crc check addr: 880c5400, length: 00000400, end_crc: 70dadb0a, crc: 8bcde759
A:在通过串口把内存中的数据dump出来时,尤其是带有PSRAM的情况,大量的数据通过串口通信可能会出错,这些是发现某段的CRC校验出错,很多时候一小段出错并不影响DEBUG。
Q:如何简单判断ELF与COREDUMP的对应关系
A:可以通过读取ELF文件与芯片上电时的时间来对比
ELF文件中的Build时间:
```
riscv64-unknown-elf-objdump -s coredump_20260604b/image_transmission_bl616cl.elf |grep -A 3 Build
80097030 0a000000 4275696c 643a3039 3a35383a ....Build:09:58:
80097040 35342c20 4a756e20 20342032 3032360d 54, Jun 4 2026.
80097050 0a000000 436f7079 72696768 74202863 ....Copyright (c
80097060 29203230 32322042 6f756666 616c6f6c ) 2022 Bouffalol
```
启动日志中的Build时间:
```
Build:09:58:54, Jun 4 2026
```