【内核崩溃kdump(sysdump)和crash分析】

本文介绍了内核崩溃时的转存机制kdump和sysdump的工作原理,以及如何利用crash工具进行内存转储文件的分析。文章详细解释了kdump的运行机制、触发方式,并对比了sysdump的特点。此外,还提供了crash工具的基本使用方法和常见命令。

内核崩溃kdump(sysdump)和crash分析

系统一旦崩溃,内核就没法正常工作了,这个时候需要触发一种转存储机制(kernel中的kdump, unisoc的sysdump)。转存机制提供一个用于捕获当前运行现场的内核,该内核会将此时内存中的所有运行状态和数据信息收集到一个dump core文件中以便之后分析崩溃原因。

在系统发生诸如Kernel crash等异常时,在Kernel中完成flush cache等处理后,重启进入dump内核收集和保存现场数据。

crash, 是某个特定时刻(如kernel panic)的系统RAM的快照,需要转存的现场数据。

约束条件:

kdump 、sysdump 通常用于假死机(unresposive)和panic,也就是没有响应的情况下。硬件问题导致的死机,无能为力。

1.kdump

kdump是kernel原生的一个系统奔溃时的现场转存工具。kdump是RHEL5之后才支持的,2006被主线接收为内核的一部分。它的原理简单来说是在内存中保留一块区域,这块区域用来存放capture kernel,当production kernel发生crash的时候,通过kexec把保留区域的capure kernel给运行起来,再由捕获内核负责把产品内核的完整信息,包括CPU寄存器、堆栈数据等转储到指定位置的文件中。

(1) kdump运行原理介绍

kdump实现了"双内核"布局,Kdump 在内核在内核panic后,立即调用kexec 引导到转储捕获内核(capture kernel),使用 kexec 引导 “覆盖” 当前运行的内核。

该“转储捕获内核”的内存区域由主内核的bootargs参数 crashkernel 或dts指定。“转储捕获内核”可以是专门build的单独 Linux 内核image,也可以在支持可重定位内核的系统架构上重用主内核映像。

kexec(kernel execution,类似于 Unix 或 Linux 的系统调用 exec)是 Linux 内核的一种机制,其允许从当前运行的内核启动新内核。kexec 会跳过由系统固件(BIOS或UEFI、bootloader)执行的引导加载程序阶段和硬件初始化阶段,直接将新内核加载到主内存并立即开始执行。这避免了完全重新启动的漫长时间,并且可以通过最小化停机时间来满足系统高可用性要求。

注意: 不经过bootloader或bios阶段,直接从主kernel启动到“转储捕获内核”进行。

图 1-1 Kdump 原理架构图

(2) dump触发方式

1.手动触发

  • 通过sysrq触发

    echo c /proc/sysrq-trigger

  • 通过IPMI触发不可屏蔽中断

    ipomitool power diag

  • 通过virsh触发不可屏蔽中断

    virsh inject-nmi MyGuestName

  • Beware of

    kernel.unkonow_nmi_panic=1

2.自动触发

  • watchdong(看门狗)

    cmdline中:nmi_watchdog=1

  • softlockup(软锁)

    sysctl kernel.softlockup_panic=1

  • 内存越界

    sysctl vm.panic_on_oom=1

3.自动触发kdump的条件

2.sysdump

SysDump即Dump system memory,是sysdump的一种转存储机制,是将发生异常时的内存信息、寄存器信息等有效信息转存为文件,以便于借助分析工具分析问题现场。

在系统发生诸如Kernel crash等异常时,在Kernel中完成flush cache等处理后,重启进入Uboot(或LK等bootloader阶段)中完成所有数据的保存,保存过程会有相应屏幕提示,完成后根据屏幕提示重启手机,导出异常数据文件进行分析。

SysDump分为FullDump和MiniDump两个子功能,两个子功能是互不影响的。

  • FullDump保存完整DDR信息,可以支持两种存储路径Dump2SD和Dump2PC。Dump2SD功能依赖于SD卡,即设备需支持插入SD卡。
  • MiniDump保存少量信息到单独的SysDumpdb分区,然后再由native sevice 程序将分区保存的raw数据整理解析后放置到/sdcard/MiniDump路径下。

MiniDump功能仅Android系统的设备支持。

在资源允许的条件下,优先选择保存分析FullDump日志,因为其保存了完整的现场信息快照,更有利于深入分析问题。

(1) sysdump运行原理介绍

2.sysdump运行原理介绍
系统异常和组合键主动触发系统异常都会走到Kernel的处理流程,但长按7s(秒)的操作不会进入Kernel处理流程。

  • MiniDump在Kernel阶段完成初始化和异常处理时的数据保存。
  • Uboot中完成数据的存储操作,包括FullDump 和MiniDump。
(2) dump触发方式

硬件配置不同,SysDump触发方式也有所差异,具体如下。

4.sysdump的触发方式

3.转存文件的解析—crash工具

前面提到,当系统崩溃时,通过kdump或sysdump可以获得当时的内存转储文件vmcore,但是该如何分析vmcore呢?

crash是一个用于分析内核转储文件的工具,一般和kdump搭配使用,sysdump也可以使用该工具解析。

使用crash时,要求调试内核vmlinux在编译时带有-g选项,即带有调试信息。如果没有指定vmcore,则默认使用实时系统的内存来分析。

值得一提的是,crash也可以用来分析实时的系统内存,是一个很强大的调试工具。crash使用gdb作为内部引擎,语法类似于gdb,命令的使用说明可以用 help来查看。

(1) crash工具的依赖

使用crash需要安装crash工具包和内核调试信息包:

crash
kernel-debuginfo-common
kernel-debuginfo

对于在PC上调试arm平台的异常现场,使用专用的crash工具,不需要安装,直接运行。
工具获取路径:
在这里插入图片描述
工具说明:
 crash_arm:用于32bit ARM 平台
 crash_arm64:用于64bit ARM 平台

(2) crash工具的使用

使用crash来调试vmcore,至少需要两个参数:

  • 未压缩的内核映像文件vmlinux。ubuntu默认位于/usr/lib/debug/lib/modules/$(uname -r)/vmlinux,由内核调试信息包提供。
  • 内存转储文件vmcore,由kdump或sysdump转存的内核奔溃现场快照。

对于ARM平台来说,除上述参数之外,一般还需要指定如下参数:

  • phys_offset: RAM的起始物理地址
  • vabits_actual: 实际的虚拟地址空间大小(总线位宽)
  • kimage_voffset: kernel image映射的物理地址偏移

以unisoc ARM64平台为例,crash执行命令:

./crash_arm64 -m vabits_actual=39 -m phys_offset=0x80000000 -m kimage_voffset=0xffffffbf90000000 ./vmlinux ./vmcore

(3) crash基本输出分析

crash基本输出:

~/crash$ ./crash_arm64_v8 -m vabits_actual=39 -m phys_offset=0x80000000 -m kimage_voffset=0xffffffbf90000000 ./vmlinux ./syscore

crash_arm64_v8 8.0.0++
Copyright (C) 2002-2021  Red Hat, Inc.
Copyright (C) 2004, 2005, 2006, 2010  IBM Corporation
Copyright (C) 1999-2006  Hewlett-Packard Co
Copyright (C) 2005, 2006, 2011, 2012  Fujitsu Limited
Copyright (C) 2006, 2007  VA Linux Systems Japan K.K.
Copyright (C) 2005, 2011, 2020-2021  NEC Corporation
Copyright (C) 1999, 2002, 2007  Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002  Mission Critical Linux, Inc.
Copyright (C) 2015, 2021  VMware, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions.  Enter "help copying" to see the conditions.
This program has absolutely no warranty.  Enter "help warranty" for details.

NOTE: setting vabits_actual to: 39

NOTE: setting phys_offset to: 0x80000000

NOTE: setting kimage_voffset to: 0xffffffbf90000000

GNU gdb (GDB) 10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=aarch64-elf-linux".
Type "show configuration" for configuration details.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...

WARNING: cpu 0: cannot find NT_PRSTATUS note
      KERNEL: ./vmlinux  [TAINTED]
    DUMPFILE: ./syscore
        CPUS: 8 [OFFLINE: 7]
        DATE: Wed Sep 14 16:38:14 CST 2022
      UPTIME: 01:48:53
LOAD AVERAGE: 10.46, 10.99, 10.55
       TASKS: 1564
    NODENAME: localhost
     RELEASE: 5.4.190-android12-9-02871-g77dc16611297
     VERSION: #1 SMP PREEMPT Wed Sep 14 10:55:40 CST 2022
     MACHINE: aarch64  (unknown Mhz)
      MEMORY: 3 GB
       PANIC: "Kernel panic - not syncing: sysrq triggered crash"
         PID: -1
     COMMAND: "bash"
        TASK: ffffff801e604b00  (1 of 32)  [THREAD_INFO: ffffff801e604b00]
         CPU: -1
       STATE: TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE|TASK_STOPPED|TASK_TRACED|EXIT_DEAD|TASK_DEAD|EXIT_ZOMBIE|TASK_WAKING|TASK_WAKEKILL|TASK_NOLOAD|TASK_NEW

crash_arm64_v8>

这些基本输出信息简单明了,可由sys命令触发。

其中各项参数的意义为:

  1. KERNEL表示调试用内核的位置和版本信息
  2. DUMPFILE: 表示所分析的内存转储镜像
  3. CPUS: 表示本机的 CPU 数目
  4. DATE: 表示内核崩溃发生的时间
  5. UPTIME: 表示内核已正常运行的时间
  6. LOAD AVERAGE: 表示内核崩溃时系统的负载
  7. TASKS: 表示内核崩溃时系统运行的任务数
  8. NODENAME: 表示内核崩溃的机器的主机名
  9. RELEASE: 表示内核的发布版本
  10. VERSION: 表示内核的其他版本信息
  11. MACHINE: 表示 CPU 的架构和主频信息
  12. MEMORY: 表示发生内核崩溃的系统的内存大小
  13. PANIC: 表示内核崩溃的类型
  14. PID: 表示导致内核崩溃的进程号;
  15. COMMAND: 表示导致内核崩溃的进程名称
  16. TASK: 表示导致内核崩溃的进程访问的内存地址;
  17. CPU: 表示导致内核崩溃的进程占用的 CPU 数目;
  18. STATE: 表示导致内核崩溃的进程的运行状态。

需要重点关注的是 13. PANIC,它告诉我们内核奔溃的原因。一般有如下类型:

  • SysRq。即通过系统请求造成的内核崩溃,如上面测试用的命令。
  • Oops。表示内核发生了不可预期的或不正确的行为,这时会杀死相应的进程,内核可能恢复正常,也可能处于一种不确定的状态,并进而导致内核的 Panic。
  • Panic。 内核崩溃,即发生了严重且不可修复的错误, 如发生了非法的地址访问, 强制加载或卸载内核模块,以及硬件错误等等。

以上信息可用于初步分析内核崩溃的原因,内核态有三种出错情况,分别是 bug, oops和 panic。 bug 属于轻微错误, oops 代表某一用户进程出现错误,需要杀死用户进程。这时如果用户进程占用了某些信号锁,这些信号锁将永远不会得到释放,这会导致系统潜在的不稳定性。 panic 是严重错误,代表整个系统崩溃。 深入的分析需要使用更多的命令进行追踪和查找。

(4) crash常用命令

查看某个命令的详细介绍:help xxx

crash_arm64_v8> help

*              files          mod            sbitmapq       union
alias          foreach        mount          search         vm
ascii          fuser          net            set            vtop
bpf            gdb            p              sig            waitq
bt             help           ps             struct         whatis
btop           ipcs           pte            swap           wr
dev            irq            ptob           sym            q
dis            kmem           ptov           sys
eval           list           rd             task
exit           log            repeat         timer
extend         mach           runq           tree

crash_arm64_v8 version: 8.0.0++   gdb version: 10.2
For help on any command above, enter "help <command>".
For help on input options, enter "help input".
For help on output options, enter "help output".

crash_arm64_v8> help xxx

1.bt命令
打印函数调用栈,displays a task’s kernel-stack backtrace 。

  • -t: 显示符号信息
  • -f: 显示栈的所有数据
  • -l: 显示文件名和行号
  • pid: 可以显示指定pid进程的backtrace
crash_arm64_v8> ps |grep UN
    161      2   4  ffffff80b62a9e00  UN   0.0       0      0  [sprd-rotation/6]
    162      2   4  ffffff80b62abc00  UN   0.0       0      0  [sprd-rotation/7]
    228      2   0  ffffff80b52be900  UN   0.0       0      0  [slog-0-0]
    730      2   0  ffffff8088c58000  UN   0.0       0      0  [RX_THREAD]
    731      2   0  ffffff8088c58f00  UN   0.0       0      0  [RX_NET_QUEUE]
    732      2   6  ffffff8088c5cb00  UN   0.0       0      0  [SPRDWL_TX_THREA]
    847      2   6  ffffff80795bbc00  UN   0.0       
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老衲不依

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值