4.6.2. mem-dump 功能指导
4.6.2.1. 概述
简介
Mem-dump,即内存转储,是指将计算机系统中某一时刻的内存内容(包括操作系统、程序、数据等)保存到文件中的过程。它通常用于故障诊断、调试、性能分析等场景。
mem-dump 信息
用户空间信息
进程内存信息
程序代码和数据:当前运行程序的代码段、数据段(例如全局变量和静态变量),堆栈、堆内存的内容等。
堆栈(Stack):堆栈中保存了当前线程的调用信息、局部变量、返回地址等。特别是在程序崩溃时,堆栈信息对于定位崩溃点至关重要。
程序计数器(Program Counter,PC):指示当前执行指令的地址,这有助于分析程序崩溃时到底执行到了哪一行代码。
线程信息
线程的堆栈信息:每个线程都有一个独立的堆栈,内存转储通常会记录每个线程的堆栈信息。线程堆栈帮助调试器了解线程执行的调用链。
线程状态:线程的运行状态,如运行、等待、阻塞等状态,以及是否发生了死锁等信息。
寄存器信息
CPU 寄存器保存了程序执行的状态信息,例如寄存器中的程序计数器(PC)、栈指针(SP)、基指针(BP)、通用寄存器等。
内存映射
进程的内存映射:包括代码段、数据段、堆、共享库、栈等的内存区域。有助于分析进程内存的分布情况。
内核信息
内核堆栈(Kernel Stack)
内核堆栈保存了内核函数的调用链,通常是操作系统内核或驱动程序在崩溃时的执行状态。
内核模块和驱动信息
内存转储会记录加载的内核模块和驱动程序的状态。有助于确定系统崩溃是否由某个特定的模块或驱动程序引起。
加载的模块:包括设备驱动、系统服务等模块,它们的内存地址、大小、状态等。
内核数据结构
内存转储可能还会包含一些重要的内核数据结构,如调度队列、进程调度信息、锁状态、文件系统状态等。
内核日志和状态信息
内核会记录有关硬件、驱动、文件系统等的状态信息。
崩溃时上下文
崩溃时的调用堆栈(Backtrace)
调用堆栈(stack trace)是最重要的崩溃分析信息之一,它提供了从崩溃点到函数调用的完整路径。
崩溃的堆栈回溯(Stack Trace)
堆栈回溯显示了程序崩溃时,所有活动线程的调用堆栈信息。
内存分配信息
一些内存转储工具可以记录内存分配的历史,如内存泄漏、过度分配等。
4.6.2.2. X5 mem-dump 功能介绍
功能特点
在进行系统调试或故障复现时,需要先配置好 mem-dump 环境(包括 PC 端和板端)。一旦系统发生 crash,通过预配置的 panic-action,可以让开发板进入不同的 boot 状态,或将内存镜像转储到指定存储介质。 这样开发人员能够在发生 crash 后及时获取内存镜像,对崩溃现场进行详细分析,快速定位问题根源,还能为后续的调试和性能优化提供重要的数据支持。
功能原理
mem-dump 是通过约定一块 uboot/kernel 都可访问的内存区域,用做标志和通知。
目前 X5 使用了 PMU 的 AON STATUS 内存区域
| 地址 | 寄存器 | 说明 |
|---|---|---|
| 0x31021000 | aon_status | aon_status 基地址 |
| 0x31021004 | panic-action | panic-action配置寄存器,表示发生 panic 后的 boot 状态类型,其 mask 为 0x0000f000 |
目前支持2种 boot 状态类型:
| Boot Index | 类型 | 说明 | 备注 |
|---|---|---|---|
| 0 | normal | 正常启动 kernel | 默认启动流程 |
| 1 | ubootonce | uboot 内等待,reset 后正常启动 | 当发生 crash 重启后进入 uboot 命令行等待,用户可执行 mem-dump 操作 |
4.6.2.3. mem-dump 配置
Kernel 提供了 sysfs 接口用于获取和配置 panic action,路径为: /sys/kernel/hobot-swinfo/panic_action
获取 panic-action
查看当前 panic-action 的状态值。
cat /sys/kernel/hobot-swinfo/panic_action
0: normal
配置 panic-action
配置 panic-action 状态类型。 以配置 panic-action 为 ubootonce 为例。
echo 1 > /sys/kernel/hobot-swinfo/panic_action
4.6.2.4. mem-dump 使用方法
配置 panic-action
针对需要重启后停留在 uboot 命令行状态的场景,可按如下操作。
配置 panic-action 为 ubootonce。
echo 1 > /sys/kernel/hobot-swinfo/panic_action
配置完成后,当故障重启,将进入 uboot 命令行

mem-dump 到 emmc 操作
在 uboot 下执行如下命令,可以将内存 dump 到 emmc 的 userdata 分区
memdump userdata
mem-dump 执行内存转储后将在 /userdata 目录生成如下文件
cpu-contexts.bin: cpu 寄存器的信息
DDRCS0-0.bin:2G 以下的内存文件
DDRCS1-0.bin: 2G 以上的内存文件,如果使用的内存大于 2G,会存在该文件
执行 mem-dump 内存转储后分析方法可参考 mem-dump 分析方法
4.6.2.5. mem-dump 分析方法
mem-dump 使用 crash 工具进行解析,用户需要使用 SDK 交付包中 software_tools\crash_tool 进行解析。crash_tool 工具包如下:
├── arm64-regs.so // arm64 寄存器扩展文件
├── crash // 调试工具
└── parse-cpu-contexts.py // python 脚本用于解析 CPU 寄存器信息
使用步骤如下
解析 cpu 的寄存器信息
python3 parse-cpu-contexts.py cpu-contexts.bin >./coreregs.txt
使用 crash 工具进入 crash 现场
./crash vmlinux文件 ./DDRCS0-0.bin@0x84000000,./DDRCS1-0.bin@0x100000000 --machdep vabits_actual=48
注意: vmlinux 文件需要与调试固件内核匹配,可以从路径 out/build/kernel/vmlinux 获取
添加扩展文件
crash> extend arm64-regs.so
./arm64-regs.so: shared object loaded
添加 cpu 寄存器信息
crash> arm64_core_set -l coreregs.txt
loading cpu core regs from coreregs.txt
loading cpu core regs from coreregs.txt done
系统调试
例如:打印栈信息
crash> bt
PID: 957 TASK: ffff0000c6be9c80 CPU: 2 COMMAND: "bash"
#0 [ffff80000d75bab0] __arm_smccc_smc at ffff800008026e8c
#1 [ffff80000d75bad0] __invoke_psci_fn_smc at ffff8000087a0f14
#2 [ffff80000d75bb10] psci_sys_reset at ffff8000087a1338
#3 [ffff80000d75bb20] atomic_notifier_call_chain at ffff800008068d10
#4 [ffff80000d75bb60] do_kernel_restart at ffff80000806b2a0
#5 [ffff80000d75bb70] machine_restart at ffff8000080188f8
PID: 957 TASK: ffff0000c6be9c80 CPU: 2 COMMAND: "bash"
#0 [ffff80000d75bab0] __arm_smccc_smc at ffff800008026e8c
#1 [ffff80000d75bad0] __invoke_psci_fn_smc at ffff8000087a0f14
#2 [ffff80000d75bb10] psci_sys_reset at ffff8000087a1338
#3 [ffff80000d75bb20] atomic_notifier_call_chain at ffff800008068d10
#4 [ffff80000d75bb60] do_kernel_restart at ffff80000806b2a0
#5 [ffff80000d75bb70] machine_restart at ffff8000080188f8
#6 [ffff80000d75bb90] emergency_restart at ffff80000806a6d4
#7 [ffff80000d75bba0] panic at ffff800008a9d6ac
#8 [ffff80000d75bc80] sysrq_handle_crash at ffff8000084fdf98
#9 [ffff80000d75bc90] __handle_sysrq at ffff8000084fe7e8
#10 [ffff80000d75bce0] write_sysrq_trigger at ffff8000084fee60
#11 [ffff80000d75bd00] proc_reg_write at ffff80000824de70
#12 [ffff80000d75bd20] vfs_write at ffff8000081d0eb0
#13 [ffff80000d75bdc0] ksys_write at ffff8000081d1264
#14 [ffff80000d75be00] __arm64_sys_write at ffff8000081d130c
#15 [ffff80000d75be10] invoke_syscall at ffff800008027014
#16 [ffff80000d75be40] el0_svc_common.constprop.0 at ffff800008027124
#17 [ffff80000d75be70] do_el0_svc at ffff80000802720c
#18 [ffff80000d75be80] el0_svc at ffff800008ab21d8
#19 [ffff80000d75bea0] el0t_64_sync_handler at ffff800008ab25a8
#20 [ffff80000d75bfe0] el0t_64_sync at ffff800008011544
4.6.2.6. 常见问题
发生 crash 前未配置 panic-action
如果发生 crash 前未配置 panic-action,可手动让开发板进入 uboot。同样可以使用命令 memdump userdata 将内存 dump 到 emmc 的 userdata 分区。
配置 panic-action 是否影响 reboot 或冷启动
对于非 panic 重启,panic-action不生效,不影响正常启动流程。