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

内存转储机制需要用到的工具kexeckdumpcrash

安装kdump确认kdump-tool是否启用修改USER_KDUMP修改crashkernel更新grub配置重启系统以使配置生效

手动触发内核崩溃,生成转储文件设置内核崩溃系统自动重启

使用crash调试查看是否存在vmlinux下载namelist:

使用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

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,也可以手动启动

sudo dpkg-reconfigure kexec-tools

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

确认kdump-tool是否启用

sudo kdump-config show

如果未安装kdump,将会提示

kdump-config: command not found

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

/etc/default/kdump-tools: USE_KDUMP is not set or zerono 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,表示启用了这个功能。

sudo dpkg-reconfigure kdump-tools

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

sudo vim /etc/default/kdump-tools

USE_KDUMP=1

配置以后再次执行

sudo kdump-config show

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

修改crashkernel

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

sudo vi /etc/default/grub.d/kdump-tools.cfg

否则,执行

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配置

sudo update-grub

重启系统以使配置生效

sudo reboot

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

第一步:

sudo sh -c "echo 1 > /proc/sys/kernel/sysrq"

第二步:

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/sysrq和echo 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使用SIGTERMi - 杀死所有进程除了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,可以通过下面的命令查看。

sudo vim /usr/src/linux-headers-$(uname -r)/.config

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

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

打开sysctl.conf文件:

sudo vim /etc/sysctl.conf

在文件末尾添加以下行以配置内核崩溃后自动重启: kernel.panic = 10 这将设置系统在内核崩溃后等待10秒后自动重启。您可以根据需要调整等待时间。 运行以下命令以使更改生效:

sudo sysctl -p

使用crash调试

查看是否存在vmlinux

ls //usr/lib/debug/boot

下载namelist:

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

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

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

执行更新源

sudo apt update

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

添加软件源公钥

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C8CAB6595FDFF622

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

再次执行

sudo apt update

下载vmlinux

sudo apt-get install linux-image-$(uname -r)-dbgsym

再次执行

ls /usr/lib/debug/boot

就能看到下载好的文件

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

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

命令格式

crash [options] namelist [dumpfile] [modpath]

其中

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

例如:

crash /usr/lib/debug/boot/vmlinux-3.13.0-24-generic /var/crash/202401021909/dump.202401021909

相关阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。