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

sudo apt install linux-crashdump

配置kexec-tools

安装时,会弹框确认是否在崩溃时,通过 kexec-tools 快速重新启动到一个新的内核,以便进行崩溃信息的收集和分析。
这里选择Yes

在这里插入图片描述
如果选择了No,也可以手动启动

sudo dpkg-reconfigure kexec-tools 

这将修改/etc/init.d/kexec中的LOAD_KEXECLOAD_KEXEC=true(未测试)

配置kdump-tools

上面的内容选择了Yes,接着继续弹出一个框,这里仍然选择Yes
在这里插入图片描述
如果选择了No,也可以手动启动(未测试)

sudo dpkg-reconfigure kdump-tools

配置成功后生成的文件

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

kdump-tools
kexec
kexec-load

确认kdump-tool是否启用

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,表示启用了这个功能。

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/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,可以通过下面的命令查看。

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

其他崩溃记录工具

Core Dump

适用场景:用户态程序崩溃

  • 概述当用户态程序(如应用程序)崩溃时,操作系统会生成一个 core dump 文件。这个文件是程序在崩溃时的内存快照,包含程序的内存、寄存器状态、堆栈信息等。
  • 用途主要用于调试和诊断应用程序崩溃问题。开发人员可以使用调试工具(如 GDB)加载 core dump 文件,分析程序崩溃的原因。
  • 生成方式:可以通过 ulimit -c 命令来控制 core dump 文件的生成。设置为非零值可以启用 core dump 功能。
  • 存储路径和命名规则:通常存储在当前工作目录或 /var/crash 目录中,文件名格式为 core.PID,例如 core.1234

Apport

适用场景:用户态程序崩溃和系统崩溃的自动报告

  • 概述:Apport 是 Ubuntu 的崩溃报告和调试工具。它自动捕获用户态程序和系统的崩溃信息,并生成崩溃报告文件。
  • 用途:主要用于自动化和简化崩溃报告过程。Apport 可以将崩溃信息发送到 Ubuntu 的崩溃报告服务器,帮助开发人员改进软件。
  • 生成方式:当一个用户态程序或系统组件崩溃时,Apport 自动捕捉崩溃事件并生成 .crash 文件,存储在 /var/crash 目录中。
  • 存储路径和命名规则:默认存储在 /var/crash 目录中,文件名格式为 program_name.PID.crash,例如 bash.1234.crash

参考

linux内核调试(四)内核转储kdump
Linux内核转储—Kdump,Crash使用介绍
ubuntu换源更新失败:The following signatures couldn‘t be verified because the public key is not available

  • 20
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
kdump是一个在Linux内核崩溃时收集dump信息的工具。它的设计目标是在遇到内核崩溃时,能够提供完整的内核转储信息,以便开发人员进行分析和调试。 kdump的工作原理是在系统启动时,设置一个保护内存区域,用于在内核崩溃时存储dump信息。当系统出现崩溃时,kdump会触发一个内核崩溃的路径,将所有的内核状态信息存储在这个保护区域中。然后,kdump会加载一个独立的小内核,这个小内核只包含了最小的功能,仅仅用于将之前存储的内核状态信息写入磁盘。这样,即使主内核发生崩溃,kdump仍然能够将dump信息保存下来。 kdump所收集的dump信息包含了内核的堆栈、寄存器的状态、内核模块列表、内核代码和数据段等。这些信息对于开发人员分析和调试内核问题非常有帮助。无论是内核中的软件错误、硬件故障还是系统配置错误,都能够通过kdump的信息来定位和解决问题。 为了使用kdump,我们首先需要安装kexec工具,然后对系统进行一些配置,如设置内存保护区域的大小、crashkernel参数等。配置完成后,重新启动系统,当系统崩溃时,kdump就会自动工作。 总结来说,kdump是一个非常有用的Linux内核调试工具,能够在内核崩溃时提供完整的dump信息,为开发人员提供了方便的分析和调试手段。它能够帮助我们快速定位和解决各种内核问题,提高系统的稳定性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值