ubuntu内核转储分析——kdump和crash的下载和使用

ubuntu内核转储分析------kdump和crash的下载和使用

内存转储机制

需要用到的工具

kexec

kexec是一个快速启动机制,允许通过已经运行的内核的上下文启动一个Linux内核,不需要经过BIOS。BIOS可能会消耗很多时间,特别是带有

众多数量的外设的大型服务器。这种办法可以为经常启动机器的开发者节省很多时间。Kexec是实现kdump机制的关键,它包括2个组成部分:

一是内核空间的系统调用kexec_load,负责在生产内核(production kernel 或 first kernel)启动时将捕获内核(capture kernel或sencond kernel)

加载到指定地址。

二是用户空间的工具kexec-tools,他将捕获内核的地址传递给生产内核,从而在系统崩溃的时候能够找到捕获内核的地址并运行。

没有kexec就没有kdump。先有kexec实现了在一个内核中可以启动另一个内核,才让kdump有了用武之地。

kdump

kdump是一种在linux内核崩溃时获取内存转储的方法,它的主要原理是为系统配置两个内核,其中用于运行正常业务的内核称为生产内核 ,而在内核崩溃时用于转储信息的内核被称为捕获内核(crash kernel)。最初系统通过生产内核启动,并在启动过程中为捕获内核保留其运行所需的内存。当系统启动完成后,它将通过应用层服务,将捕获内核镜像加载到其对应的保留内存中。此后,生产内核就可像其它系统一样,正常地处理相关的业务。

若内核在运行中发生崩溃,且已设置了捕获内核,则生产内核则会首先准备好转储文件,然后启动捕获内核。捕获内核启动以后,将会生成转储文件vmcore。

crash

当 linux 系统内核发生崩溃的时候,生成了转储文件 vmcore。而后通过分析该 vmcore 文件就可以诊断出内核崩溃的原因,从而进行操作系统的代码改进。而 crash 就是一个被广泛使用的内核崩溃转储文件分析工具。

安装kdump

bash 复制代码
sudo apt install linux-crashdump

修改kexec-tools

|------------------------| Configuring kexec-tools |-------------------------------------|

| |

| |

| If you choose this option, a system reboot will trigger a restart into a |

| kernel loaded by kexec instead of going through the full system boot |

| loader process. |

| |

| Should kexec-tools handle reboots (sysvinit only)? |

| |

| |

| |

|------------------------------------------------------------------------------------------------|

安装成功后,将会在/etc/init.d中多了几个文件

kdump-tools

kexec

kexec-load

如果选择了No,也可以手动启动

bash 复制代码
sudo dpkg-reconfigure kexec-tools

这将修改/etc/init.d/kexec中的LOAD_KEXEC ,LOAD_KEXEC=true

确认kdump-tool是否启用

bash 复制代码
sudo kdump-config show

如果未安装kdump,将会提示

kdump-config: command not found

如果安装了kdump-config, 将会提示:

  • /etc/default/kdump-tools: USE_KDUMP is not set or zero
  • no crashkernel= parameter in the kernel cmdline
    dpkg-query: package 'kdump-tools' is not installed and no information is available

修改USER_KDUMP

这个参数默认是0,有文章说可以通过下面命令修改/etc/default/kdump-tools 文件中的 USE_KDUMP 参数为 1,表示启用了这个功能。

bash 复制代码
sudo dpkg-reconfigure kdump-tools

经过实测(包括重启)并没有什么效果,不清楚是什么原因。因此只能手动修改该参数

bash 复制代码
sudo vim /etc/default/kdump-tools
USE_KDUMP=1

配置以后再次执行

bash 复制代码
sudo kdump-config show

将不会提示 * /etc/default/kdump-tools: USE_KDUMP is not set or zero

修改crashkernel

如果存在/etc/default/grub.d/kdump-tools.cfg这个文件,执行

bash 复制代码
sudo vi /etc/default/grub.d/kdump-tools.cfg

否则,执行

bash 复制代码
sudo vi /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT=""中的参数修改为
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT crashkernel=384M-:512M"

这个参数的格式是crashkernel=[总内存范围]:[保留内存大小]

  • [总内存范围]可以是一个具体的内存大小,也可以是一个范围。例如,384M-表示总内存大小在384M以上。
    [保留内存大小]则是你想要保留的内存大小。这部分内存将在系统启动时被预留出来,用于在系统崩溃时保存内核转储。

所以384M-:512M这个参数的意思是,对于总内存大小在384M以上的系统,保留512M的内存用于内核转储。

更新grub配置

bash 复制代码
sudo update-grub

重启系统以使配置生效

bash 复制代码
sudo reboot

手动触发内核崩溃,生成转储文件

第一步:

bash 复制代码
sudo sh -c "echo 1 > /proc/sys/kernel/sysrq"

第二步:

bash 复制代码
sudo sh -c "echo c > /proc/sysrq-trigger"

这里不直接使用sudo echo x > /proc/xxx/xxx/xxx的原因是使用它会报错Permission denied,是因为重定向符号 ">" 也是 bash 的命令。sudo 只是让 echo 命令具有了 root 权限,但是没有让 ">" 命令也具有root 权限,所以 bash 会认为这个命令没有写入信息的权限。

其中echo 1 > /proc/sys/kernel/sysrqecho c > /proc/sysrq-trigger是用来触发SysRq功能的命令。SysRq功能是一种种魔术系统请求键,可以让用户向内核发送一些特殊的命令,以获取或控制系统的信息或状态。

echo 1 > /proc/sys/kernel/sysrq向sysrq文件中写入1是为了开启SysRq功能(写入0是关闭SysRq功能),但是这需要内核支持(CONFIG_MAGIC_SYSRQ选项),它会让内核响应用户输入的任何操作,只要内核没有挂掉。此功能只是临时开启,重启后SysRq会自动关闭。如果想让此功能一直生效,在/etc/sysctl.conf里面设置kernel.sysrq的值为1. 重新启动以后,此功能将会自动打开。

echo c > /proc/sysrq-trigger是用来触发故意让系统统崩溃(crash)命令的命令,它会让内核立即即崩溃,并且不会管你有没有数据没有写回回磁盘,也不卸载载磁盘,而是完完全全地关机。

执行后,等待系统重启,在/var/crush中会生成几个文件,

root@ubuntu10:/var/crash# tree .

.

├── 202401021909

│ ├── dmesg.202401021909

│ └── dump.202401021909

├── kexec_cmd

└── linux-image-3.13.0-24-generic-202401021909.crash

其中

  • kexec_cmd是默认就有的
  • dmesg.202401021909:这个文件是系统内核崩溃时的内核日志,它记录了内核崩溃的原因和上下文信息,可以用来分析内核崩溃的原因和过程。
  • dump.202401021909:这个文件是系统内核崩溃时的内核内存转储文件,它包含了内核崩溃时的内存状态,可以用来分析内核崩溃的现场和数据。
  • linux-image-3.13.0-24-generic-202401021909.crash:这个文件是系统内核崩溃时,使用apport命令来生成的崩溃报告文件,它包含了系统内核的版本和配置信息,以及内核崩溃的时间和环境信息,可以用来报告和追踪内核崩溃的问题。

补充知识一:sysrq的参数

  • b - 即时重新启动系统
  • o - 即时关机
  • s - 即时同步所有挂载的文件系统
  • u - 即时重新挂载所有的文件系统为只读
  • p - 导出当前CPU寄存器信息和标志位的信息
  • t - 导出线程状态信息
  • m - 导出关于内存分配的信息
  • c - 故意让系统统崩溃(在使用netdump或diskdump的时候有用)
  • e - 杀死所有进程除了init使用SIGTERM
  • i - 杀死所有进程除了init使用SIGKILL

当一个sysrq命令被触发,内核将会打印信息到内核的环形缓冲并输出到系统控制台。此信息一般也会通过syslog输出到/var/log/messages/var/log/syslog。有时候,可能系统已无法响应,syslogd可能无法记录此信息。在这种情况下,建议你设置一个串口终端来收集这个信息。

补充知识二:CONFIG_XXX参数一般不需要修改

有的文章linux内核调试(四)内核转储kdump说,在安装kdump后,需要修改这几个参数,来支持kexec

CONFIG_KEXEC=y

CONFIG_SYSFS=y

CONFIG_DEBUG_KERNEL=y

CONFIG_CRASH_DUMP=y

CONFIG_PROC_VMCORE=y

CONFIG_DEBUG_INFO=y

这些针对的是高阶用户的,实际上除了CONFIG_DEBUG_INFO外,其他几个参数默认都是y,可以通过下面的命令查看。

bash 复制代码
sudo vim  /usr/src/linux-headers-$(uname -r)/.config

据说CONFIG_DEBUG_INFO开启后,会使得编译出的内核和模块文件的大小大大增加,所以一般也不需要选。

设置内核崩溃系统自动重启

打开sysctl.conf文件:

bash 复制代码
sudo vim /etc/sysctl.conf

在文件末尾添加以下行以配置内核崩溃后自动重启:
kernel.panic = 10

这将设置系统在内核崩溃后等待10秒后自动重启。您可以根据需要调整等待时间。

运行以下命令以使更改生效:

bash 复制代码
sudo sysctl -p

使用crash调试

查看是否存在vmlinux

bash 复制代码
ls //usr/lib/debug/boot

下载namelist:

namelist是一个包含了内核调试符号的vmlinux内核镜像文件

内核调试符号是指包含了调试信息的内核镜像文件,它可以帮助开发者或者分析者定位内核的错误或者性能问题。

添加一个新的源到/etc/apt/sources.list.d

bash 复制代码
echo "deb http://ddebs.ubuntu.com $(lsb_release -cs)-updates main restricted universe multiverse
deb http://ddebs.ubuntu.com $(lsb_release -cs)-security main restricted universe multiverse
deb http://ddebs.ubuntu.com $(lsb_release -cs)-proposed main restricted universe multiverse" | \
sudo tee -a /etc/apt/sources.list.d/ddebs.list

执行更新源

bash 复制代码
sudo apt update

如果报错The following signatures couldn't be verified because the public key is not available: NO_PUBKEY C8CAB6595FDFF622

添加软件源公钥

bash 复制代码
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C8CAB6595FDFF622

这里的keys后面的值,填写报错信息里面信息里面NO_PUBKEY后的值

再次执行

bash 复制代码
sudo apt update

下载vmlinux

bash 复制代码
sudo apt-get install linux-image-$(uname -r)-dbgsym

再次执行

bash 复制代码
ls /usr/lib/debug/boot

就能看到下载好的文件

下载指定的vmlinux内核镜像如果上面的方法行不通,还有其他两种方法,参见Ubuntu安装上的vmlinux在哪里?

使用crash命令查看内核转储文件

命令格式

bash 复制代码
crash [options] namelist [dumpfile] [modpath]

其中

  • namelist是一个包含了内核调试符号的内核镜像文件
  • dumpfile是一个内核崩溃数据文件或者实时系统的设备名
  • modpath是一个包含了内核模块的目录

例如:

bash 复制代码
crash /usr/lib/debug/boot/vmlinux-3.13.0-24-generic /var/crash/202401021909/dump.202401021909
相关推荐
kikikidult12 小时前
(2025.07)解决——ubuntu20.04系统开机黑屏,左上角光标闪烁
笔记·ubuntu
BD_Marathon15 小时前
Ubuntu:Mysql服务器
服务器·mysql·ubuntu
0wioiw016 小时前
Ubuntu基础(监控重启和查找程序)
linux·服务器·ubuntu
Tipriest_17 小时前
Ubuntu常用的软件格式deb, rpm, dmg, AppImage等打包及使用方法
linux·运维·ubuntu
GBXLUO17 小时前
windows的vscode无法通过ssh连接ubuntu的解决办法
vscode·ubuntu
笑衬人心。19 小时前
Ubuntu 22.04 修改默认 Python 版本为 Python3 笔记
笔记·python·ubuntu
物联网老王1 天前
Ubuntu Linux Cursor 安装与使用一
linux·运维·ubuntu
fangeqin2 天前
ubuntu源码安装python3.13遇到Could not build the ssl module!解决方法
linux·python·ubuntu·openssl
风口上的吱吱鼠2 天前
Armbian 25.5.1 Noble Gnome 开启远程桌面功能
服务器·ubuntu·armbian
笑衬人心。2 天前
Ubuntu 22.04 + MySQL 8 无密码登录问题与 root 密码重置指南
linux·mysql·ubuntu