Kernel Crash kdump 使用指南
荣涛 2021年10月12日

1. 内存要求

首先查看CPU架构uname -m,然后参考链接Section 7.8.1, “Memory requirements for kdump“

CPU架构 可用内存 Crash预留内存
AMD64 和 Intel 64 (x86_64) 2 GB + 161 MB + 64 MB 每 1 TB
64-bit ARM 架构 (arm64) 2 GB + 512 MB

1.1. 估计kdump大小

$ sudo makedumpfile -f --mem-usage /proc/kcore TYPE      PAGES           EXCLUDABLE  DESCRIPTION
----------------------------------------------------------------------
ZERO        28670               yes     Pages filled with zero
NON_PRI_CACHE   875525              yes     Cache pages without private flag
PRI_CACHE   159                 yes     Cache pages with private flag
USER        311449              yes     User process pages
FREE        2479751             yes     Free pages
KERN_DATA   386929              no      Dumpable kernel data page size:     4096
Total pages on system:  4082483
Total size on system:   16721850368      Byte

2. 安装kdump

2.1. yum安装kdump

$ sudo yum install kexec-tools
$ rpm -qa kexec-tools
kexec-tools-2.0.20-46.el8_4.2.x86_64

如果需要图形配置工具,请执行:

$ sudo yum install system-config-kdump

2.2. 源码安装kdump

源码链接:

  • http://kernel.org/pub/linux/utils/kernel/kexec/kexec-tools.tar.gz
  • http://www.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git
tar xvpzf kexec-tools.tar.gz
cd kexec-tools-VERSION
./configure
make
make install

3. 配置kdump

3.1. 内核编译配置需求

参见链接:System kernel config options

CONFIG_KEXEC=y or CONFIG_KEXEC_FILE=y
CONFIG_KEXEC_CORE=y
CONFIG_CRASH_CORE=y
CONFIG_SYSFS=y
CONFIG_DEBUG_INFO=Y
CONFIG_CRASH_DUMP=y
CONFIG_PROC_VMCORE=y
CONFIG_HIGHMEM64G=y
CONFIG_RELOCATABLE=y

3.2. 配置kdump命令行

配置系统的boot loader配置文件crashkernel=,依照上面说的需要预留的内存大小,进行设置,如:

crashkernel=128M

语法为:

crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset]
range=start-[end]

所以这个参数也可以定义为动态参数:

crashkernel=512M-2G:64M,2G-:128M

或者:

crashkernel=128M@16M

上面的参数,在文件/etc/grub2-efi.cfg(不同系统,这个文件可能有差异)。

先查看当前的内核命令行:

$ cat /proc/cmdline
BOOT_IMAGE=(hd0,gpt2)/vmlinuz-4.18.0-30501.10.2.el8.x86_64 root=/dev/mapper/cl-root ro crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet

打开文件/etc/grub2-efi.cfg

$ sudo vim /etc/grub2-efi.cfg

在其中一行找到:

if [ -z "${kernelopts}" ]; thenset kernelopts="root=/dev/mapper/cl-root ro crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet "
fi

我们要做的,就是在变量kernelopts中添加crashkernel=参数:

if [ -z "${kernelopts}" ]; thenset kernelopts="root=/dev/mapper/cl-root ro crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet crashkernel=128M"
fi

3.3. 配置kdump类型

当内核crash时候,产生的coredump文件可以存在一个文件系统的文件中,也可以发送到网络文件系统NFS,或者SSH协议中。当然只能选择其中之一:

  1. 文件系统;
  2. NFS
  3. SSH

3.3.1. vmcore保存到本地文件系统

编辑文件/etc/kdump.conf

path /var/crash

说明,vmcore会保存在路径/var/crash下。你可以修改这个路径到任意路径,如:

path /usr/local/cores

如果vmcore存在了/var/crash/var/crash中,那么/etc/kdump.conf文件可能为:

grep -v ^# etc/kdump.conf | grep -v ^$
ext4 /dev/mapper/vg00-varcrashvol
path /var/crash
core_collector makedumpfile -c --message-level 1 -d 31

这种情况把path /var/crash改为path /即可。

3.3.2. vmcore保存到nfs

略,参见CHAPTER 7. KERNEL CRASH DUMP GUIDE。

3.3.3. vmcore保存到ssh

略,参见CHAPTER 7. KERNEL CRASH DUMP GUIDE。

3.4. 配置core收集器

为了减小coredump文件大小,kdump与虚拟定义一个外部的应用压缩数据,当前,唯一的collector是 makedumpfile
为了使能core收集器,需要把/etc/kdump.conf中原有的:

core_collector makedumpfile -l --message-level 7 -d 31

--message-level指定了信息收集的级别,1为只打印process indicator 日志信息,默认值为7,具体见下表:

Message | progress    common    error     debug     report
Level   | indicator   message   message   message   message
---------+------------------------------------------------------0 |1 |     X2 |                X4 |                          X* 7 |     X          X         X8 |                                    X16 |                                              X31 |     X          X         X         X         X

-d 指定了kdump的过滤级别,具体见下表:

       |         cache    cacheDump  |  zero   without  with     user    freeLevel |  page   private  private  data    page
-------+---------------------------------------0  |1  |   X2  |           X4  |           X       X8  |                           X16  |                                    X31  |   X        X      X       X        X

31表示过滤掉以上五种全部信息,这样kdump生成的速度就会更快,生成的vmcore文件也会较小。如果此处使用值0 ,表示不过滤任何信息,在kdump生成时,会记录主机当前的所有信息。这就是为什么在kdump生成时,有些主机只有几十M大小生成,有些主机确有几十 G大小的原因。更多用法可以查看makedumpfile命令的帮助文档。

注释掉原有的(或者直接使用原有的也可以):

# core_collector makedumpfile -l --message-level 7 -d 31

为了使能dump文件压缩,使用选项-l

core_collector makedumpfile -l

为了移除特定的page,使用-d value参数,例如,为了移除零页和空闲页,可以使用:

core_collector makedumpfile -d 17 -c

详情请参考makedumpfile(8)手册。

3.5. 配置默认动作

kdump将直接保存coredump到特定的类型中(上面已经提到:本地文件系统,NFS,SSH)。
默认情况下,kdump将重启系统:

default reboot

我把它设置为:

default dump_to_rootfs

在文件/etc/kdump.conf中有注释:

# default <reboot | halt | poweroff | shell | dump_to_rootfs>
#           - Same as the "failure_action" directive above, but this directive
#             is obsolete and will be removed in the future.
#

他们的含义如下:

  • dump_to_rootfs: 尝试将核心转储保存到根文件系统。此选项与网络目标结合使用时特别有用:如果网络目标不可访问,此选项将配置 kdump 以在本地保存核心转储。系统随后重新启动。
  • reboot: 重新启动系统,在此过程中丢失核心转储。
  • halt: 停止系统,在此过程中丢失核心转储。
  • poweroff: 关闭系统电源,在此过程中丢失核心转储。
  • shell: 从 initramfs 中运行 shell 会话,允许用户手动记录核心转储。

参见链接:支持的默认操作

3.6. 使能kdump服务

查看当前kdump服务状态:

$ systemctl status kdump
● kdump.service - Crash recovery kernel armingLoaded: loaded (/usr/lib/systemd/system/kdump.service; enabled; vendor preset: enabled)Active: active (exited) since Mon 2021-10-11 09:09:14 CST; 1 day 10h agoMain PID: 2281 (code=exited, status=0/SUCCESS)Tasks: 0 (limit: 99096)Memory: 0BCGroup: /system.slice/kdump.service

如果没有启动,手动启动kdump:

$ sudo systemctl start kdump.service

设置开机自启:

$ sudo systemctl enable kdump.service

3.7. kdump涉及的sysctl 配置

在配置kdump时,对sysctl.conf 内的一些配置也进行了调整。这里也列举下,可以根据具体的情况酌情进行修改。

kernel.sysrq=1
kernel.unknown_nmi_panic=1
kernel.softlockup_panic=1
  • kernel.sysrq=1,如果通过/proc文件配置 ,上面的配置等价于echo 1 > /proc/sys/kernel/sysrq ,打开sysrq键的功能以后,有终端访问权限的用户将会拥有一些特别的功能。如果系统出现挂起的情况或在诊断一些和内核相关,
    使用这些组合键能即时打印出内核的信息。因此,除非是要调试,解决问题,一般情况下,不要打开此功能。如果一定要打开,请确保你的终端访问的安全性。具体可以参看百度百科上给出的解释。

  • kernel.unknown_nmi_panic=1 ,如果系统已经是处在Hang的状态的话,那么可以使用NMI按钮来触发Kdump。开启这个选项可以:echo 1 > /proc/sys/kernel/unknown_nmi_panic 需要注意的是,启用这个特性的话,是不能够同时启用NMI_WATCHDOG的!否则系统会Panic!

  • kernel.softlockup_panic=1,其对应的是/proc/sys/kernel/softlockup_panic的值,值为1可以让内核在死锁或者死循环的时候可以宕机重启。如果你的机器中安装了kdump,在重启之后,你会得到一份内核的core文件,这时从core文件中查找问题就方便很多了,而且再也不用手动重启机器了。如果你的内核是标准内核的话,可以通过修改/proc/sys/kernel/softlockup_thresh来修改超时的阈值,如果是CentOS内核的话,对应的文件是/proc/sys/kernel/watchdog_thresh。

除此之外,一些站点上还会建议修改开启oops painc的功能,这个也具体根据实际需要修改吧。

3.8. 在图形界面下配置kdump

略,参考:Basic Setting。

4. 加载Dump-capture Kernel

参考链接:Load the Dump-capture Kernel

在启动系统内核后,dump-capture内核需要加载。根据不同的架构,可以选择加载vmlinux或者压缩的bzImage/vmlinuz的dump-capture内核。

架构 选项
i386/x86_64 如果内核可重定向,选择bzImage/vmlinuz
如果内核不可重定向,选择vmlinuz
ppc64 vmlinux
s390x imagebzImage
ia64 vmlinuxvmlinuz.gz
arm zImage
arm64 vmlinuxImage
  • 如果使用非压缩的vmlinux image,使用下面的命令行加载dump-capture 内核:
kexec -p <dump-capture-kernel-vmlinux-image> \--initrd=<initrd-for-dump-capture-kernel> --args-linux \--append="root=<root-dev> <arch-specific-options>"
  • 如果使用压缩的bzImage/vmlinuz,使用下面的命令行加载dump-capture 内核:
kexec -p <dump-capture-kernel-bzImage> \--initrd=<initrd-for-dump-capture-kernel> \--append="root=<root-dev> <arch-specific-options>"
  • 如果使用压缩的zImage,使用下面的命令行加载dump-capture 内核:
kexec --type zImage -p <dump-capture-kernel-bzImage> \--initrd=<initrd-for-dump-capture-kernel> \--dtb=<dtb-for-dump-capture-kernel> \--append="root=<root-dev> <arch-specific-options>"
  • 如果使用非压缩的Image,使用下面的命令行加载dump-capture 内核:
kexec -p <dump-capture-kernel-Image> \--initrd=<initrd-for-dump-capture-kernel> \--append="root=<root-dev> <arch-specific-options>"

注意:
--args-linux在ia64中不需要。

下面是一些架构特有的参数:

架构 选项参数
i386, x86_64, ia64 “1 irqpoll nr_cpus=1 reset_devices”
ppc64 “1 maxcpus=1 noirqdistrib reset_devices”
s390x “1 nr_cpus=1 cgroup_disable=memory”
arm “1 maxcpus=1 reset_devices”
arm64 “1 nr_cpus=1 reset_devices”

加载dump-capture内核的注意事项:

  • 默认情况下,ELF 标头以 ELF64 格式存储,以支持超过 4GB 内存的系统。在 i386 上,kexec 会自动检查物理 RAM 大小是否超过 4 GB 限制,如果没有,则使用 E​​LF32。因此,在非 PAE 系统上,始终使用 ELF32。

    • --elf32-core-headers 选项可用于强制生成 ELF32 标头。这是必要的,因为 GDB 当前无法在 32 位系统上打开带有 ELF64 标头的 vmcore 文件。
  • irqpoll”引导参数减少了由于转储捕获内核中的共享中断导致的驱动程序初始化失败。

  • 您必须以与 mount 命令输出中的根设备名称对应的格式指定 。

  • 引导参数“1”将转储捕获内核引导至单用户模式,无需联网。如果您想要联网,请使用“3”。

  • 我们通常不必为了捕获转储而启动 SMP 内核。因此,通常构建 UP 转储捕获内核或在加载转储捕获内核时指定 maxcpus=1 选项很有用。请注意,尽管 maxcpus 始终有效,但如果当前 ARCH(例如 x86)支持,您最好将其替换为 nr_cpus 以节省内存。

  • 如果您打算使用多线程程序,您应该在转储捕获内核中启用多 CPU 支持,例如 makedumpfile 的并行转储功能。否则,多线程程序可能会有很大的性能下降。要启用多 CPU 支持,您应该启动 SMP 转储捕获内核并在加载时指定 maxcpus/nr_cpusdisable_cpu_apicid=[X] 选项。

  • 对于 s390x,有两种 kdump 模式: 如果使用 elfcorehdr= kernel 参数指定了 ELF 标头,则 kdump 内核将使用它,就像在所有其他架构上一样。如果未指定 elfcorehdr= 内核参数,则 s390x kdump 内核会动态创建标头。第二种模式的优点是对于 CPU 和内存热插拔,kdump 不必使用 kexec_load() 重新加载。

  • 对于具有许多附加设备的 s390x 系统,应该将“cio_ignore”内核参数用于 kdump 内核,以防止为与 kdump 无关的设备分配内核内存。这同样适用于使用 SCSI/FCP 设备的系统。在这种情况下,在将 FCP 设备设置为在线之前,应将“allow_lun_scan”zfcp 模块参数设置为零。

5. 内核驱动kdump黑名单

在文件/etc/sysconfig/kdumpKDUMP_COMMANDLINE_APPEND=参数中添加:

KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory mce=off numa=off udev.children-max=2 pani    c=10 rootflags=nofail acpi_no_memhotplug transparent_hugepage=never nokaslr novmcoredd hest_disable"

并且知名下面其中之一:

  • rd.driver.blacklist=<modules>
  • modprobe.blacklist=<modules>

步骤如下:

  1. 选择一个需要加入黑名单的模块:
$ lsmod
Module                  Size  Used by
macvtap                16384  0
macvlan                28672  1 macvtap
tap                    28672  1 macvtap
loadavg_proc_show      16384  0
binfmt_misc            20480  1
xt_CHECKSUM            16384  1
[...]
  1. 更新文件/etc/sysconfig/kdumpKDUMP_COMMANDLINE_APPEND=参数:
KDUMP_COMMANDLINE_APPEND="rd.driver.blacklist=fuse irqpoll nr_cpus=1 reset_devices cgroup_disable=memory mce=off numa=off     udev.children-max=2 panic=10 rootflags=nofail acpi_no_memhotplug transparent_hugepage=never nokaslr novmcoredd hest_disa    ble"

当然,也可以改为:

KDUMP_COMMANDLINE_APPEND="modprobe.blacklist=fuse irqpoll nr_cpus=1 reset_devices cgroup_disable=memory mce=off numa=off     udev.children-max=2 panic=10 rootflags=nofail acpi_no_memhotplug transparent_hugepage=never nokaslr novmcoredd hest_disa    ble"
  1. 重启kdump服务:
$ sudo systemctl restart kdump

重启需要好几秒。

6. 测试kdump

6.1. kdump Panic

下面的命令将导致内核奔溃crash,不要用于生产环境。
下面的命令将导致内核奔溃crash,不要用于生产环境。
下面的命令将导致内核奔溃crash,不要用于生产环境。

查看kdump是否激活:

$ sudo systemctl is-active kdump
active

然后执行下面两行指令:

$ su
# echo 1 > /proc/sys/kernel/sysrq
# echo c > /proc/sysrq-trigger

上面的两条指令,导致内核crash,文件address-YYYY-MM-DD-HH:MM:SS/vmcore将被拷贝到上面配置文件/etc/kdump.conf指定的文件路径path /var/crash中。

6.2. 写dump文件

在dump-capture内核启动之后,写出dump文件:

cp /proc/vmcore <dump-file>

你也可以使用makedumpfile工具指定特定的过滤规则:

makedumpfile -l --message-level 1 -d 31 /proc/vmcore <dump-file>

6.3. gdb分析

分析之前,你应该重启系统。使用gdb调试:

gdb vmlinux <dump-file>

6.4. crash分析

也可以使用crash工具进行分析,链接如下:

  • https://github.com/crash-utility/crash
  • https://crash-utility.github.io/

例:

crash /usr/lib/modules/4.18.0-30501.10.2.el8.x86_64/vmlinuz vmcore

7. 参考链接

7.1. 文章

  • CHAPTER 7. KERNEL CRASH DUMP GUIDE
  • Section 7.8.1, “Memory requirements for kdump“
  • CHAPTER 3. LISTING OF KERNEL PARAMETERS AND VALUES
  • Linux Documentation for Kdump - The kexec-based Crash Dumping Solution
  • http://horms.net/projects/kexec/
  • https://crash-utility.github.io/
  • centos配置kdump捕获内核崩溃
  • 5分钟搞懂kexec工作原理

7.2. 源码

  • http://kernel.org/pub/linux/utils/kernel/kexec/kexec-tools.tar.gz
  • http://www.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git
  • https://github.com/crash-utility/crash

8. 附录

8.1. kexec工作原理

参考:5分钟搞懂kexec工作原理

kexec可从当前正在运行的内核直接跳转到新内核,kexec整体思路如下

  1. 新的kernel镜像和initrd镜像连续存储在内存中,initrd的位置记录在boot_params中
  2. 切换到新内核就是跳转到新的kernel镜像所在内存位置,CPU执行其entry的代码即可,新的内核通过boot_params记录的initrd位置完成根文件系统内容的加载

8.2. kdump执行流程

参考:centos配置kdump捕获内核崩溃


8.3. crash分析

略。

crash /usr/lib/modules/4.18.0-30501.10.2.el8.x86_64/vmlinuz vmcore
Copyright (C) CESTC Com.

Kernel Crash kdump 使用指南相关推荐

  1. 最新历史版本 :LINUX KERNEL 配置编译中文指南

    LINUX KERNEL 配置编译中文指南 序言 近几年,linux大行其道,令不满windows蓝屏的使用者跃跃欲试,结果发现linux安装不及windows方便,界面不及windows友好,配置不 ...

  2. Kernel crash:总结

    文章目录 crash list timer 现场debug crash 常用的脚本 及常用命令 log 手动生成kernel crash 注意事项 手动crash的backtrace 在crash里可 ...

  3. Crash+Kdump 分析内核崩溃内存转储文件之环境搭建

    虚拟机环境为centos 5.5 32bit kdump 服务和kexec-tools 检查kexec-tools: rpm -qa|grep kexec-tools 如果没有安装,yum insta ...

  4. Linux Kernel Crash Dump note

    how to use crash utility to analyze vmcore files. 内核调试方法 使用crash工具查看定位linux内核崩溃原因: [root@mi_cct vmco ...

  5. 怎样保存kernel crash dump 文件

    1.概述 实现Linuxkernel crashdump的保存,包括两部分.当kernel异常后,需要系统重启,且重启方式和正常的重启(上电重启)区别开:当系统重启后,判断重启的原因,如果是内核中设置 ...

  6. kernel crash kernel tried to execute NX-protected page

    环境 Red Hat Enterprise Linux 6, 7 RHEL 7 kernel-3.10.0-514.2.2.el7 RHEL 6 kernel-2.6.32-220.13.1.el6 ...

  7. Linux kernel crash定位

    # aarch64-linux-android-addr2line -f -e out/target/product/msmxxx/obj/kernel/msm-3.18/vmlinux ffffff ...

  8. Kernel Panic (Kdump) 解析实例之二:内存溢出

    关于怎么打开core文件,参见上一篇,这里不罗嗦了. 1) 首先,这个panic跟内存使用越界有关.先来看看导致panic的call trace和寄存器. RIP: 0010:[<fffffff ...

  9. Android kernel Crash后,定位出错点的方法

    1. 将/prebuild/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/arm-linux-androideabi-gdb 拷贝到/usr/loca ...

最新文章

  1. 使用深度学习检测混凝土结构中的表面裂缝
  2. 端到端半监督目标检测框架
  3. RDKit | 基于主成分分析可视化(DrugBank)类药性的化学空间
  4. Spring @Lazy
  5. 一张图解释什么是遗传算法_一张图告诉你什么叫真正的满配m416,吃鸡玩家看懵了...
  6. 统计每日单量MySQL语句
  7. 使用js设置ul标签的显示或隐藏和超链接调用js文件的方法
  8. 函数指针史上最全的介绍
  9. PyCharm安装与配置,python的Hello World
  10. Spring mvc @SessionAttribute
  11. 用GDB调试程序(10)──查看运行时数据(1)-转
  12. git stash暂存命令
  13. ICPC North Central NA Contest 2017 E - Is-A? Has-A? Who Knowz-A?
  14. java 中文字符串 排序_Java实现对中文字符串的排序功能实例代码
  15. excel 工作表保护密码破解代码
  16. SIGKDD2021 | 淘宝搜索向量化召回实践
  17. 【Ubuntu】安装H.264解码器
  18. HTML5期末大作业 漫画网站设计——动漫海贼王(10页) 动漫网页设计制作 简单静态HTML网页作品 动漫网页作业成品 学生动漫网站模板
  19. 【Spring练习】Spring+SpringMVC+JdbcTemplate简单练习用户管理
  20. 通过多视图信息瓶颈学习鲁棒表征

热门文章

  1. springmvc处理器及前端控制器介绍
  2. Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
  3. manjaro配置zsh和oh-my-zsh
  4. mysql8.0 利用docker容器安装配置多主多从集群
  5. VUE 全局监听sessionStorage变化
  6. Is it cold in Shinjuku?
  7. .net Api 接口调用 增删改查
  8. ASC2 E Quantization Problem DP
  9. 页面缓存,数据源缓存
  10. MySQL update For_mysql SELECT FOR UPDATE语句使用示例