在我的上一篇博文《Linux内核的Oops》的最后介绍到一个Linux内核转储工具Kdump,这个工具可以在发生kernel panic时把现场dump到一个文件里,以供后续分析之用。本文主要介绍在Ubuntu下如何使用kdump。
Kdump是一个通用的Linux内核转储工具,详细的用法说明可以参考这篇Kdump Tutorial。这篇教程洋洋洒洒几十页(链接里有pdf文件可以下载),详细介绍了内核配置的参数,以及实现内核崩溃转储的一系列工具的用法以及可能出现的问题,过程看上去有点繁琐。是不是每台需要调试的机器都要这么设置呢?其实是没有必要的。Linux发行版已经帮我们做了很大一部分工作,我们需要做的只是安装几个包,启动一下Kdump服务就可以了。很多发行版比如Ubuntu默认在内核里已经支持了Kdump,我们并不需要重新配置内核,kdump的一系列工具也做成了service可以直接启用。接下来,我们就会看到在Ubuntu上使用kdump真的非常简单。但是,我还是建议大家在完成这个简单的流程后,再回过头来仔细阅读上面提到的教程,毕竟,知道真正的细节才能有助于我们更好的理解这个系统。
Kdump简介
Kdump是一个Linux内核崩溃转储机制,这个机制的原理是在内存中保留一块区域,这块区域用来存放capture kernel,当前的内核发生crash后,通过kexec把保留区域的capture kernel运行起来,由capture kernel负责把crash kernel的完整信息--包括CPU寄存器、堆栈数据等--转储到文件中,文件的存放位置可以是本地磁盘,也可以是网络。
安装Ubuntu的crashdump工具包
在Ubuntu下实现Kdump只需要安装linux-crashdump这个包就可以了,可以在新立得下搜索linux-crashdump或者用命令:
sudo apt-get install linux-crashdump
linux-crashdump实际上安装了三个工具,分别是:crash,kexec-tools,以及makedumpfile。
安装完毕以后,我们检查一下grub2的启动选项,会发现在引导内核的命令linux后面多了一个参数:
crashkernel=384M-2G:64M,2G-:128M
crashkernel用来指定保留内存的大小,语法定义如下:
crashkernel=
: [, : ,...][@offset] range=start-[end]
其中,start包含在指定范围内,而end不包含在指定范围内。
参考这个语法定义,我们就可以知道linux-crashkernel帮我们设定的保留区域的大小是:如果内存小于384M,不保留内存;如果内存大于等于384M但小于2G,保留64M;如果内存大于2G,保留128M。
在/etc/init.d中还会有一个kdump的service脚本,我们可以打开这个脚本看一看,内容很简单,主要是用kexec把/boot下的linux内核镜像当作capture kernel放入保留内存里。
试用Kdump
在下面的实例中,所有的操作都需要root权限,所以请先用sudo su切换到root。
我们需要首先启动kdump service,命令如下:
service kdump start
下面是启动成功的画面:
写一个让内核崩溃的模块还是比较麻烦的,我们可以通过SysRq来实现这个目的。注意,在进行下面的操作前,请保存好自己的数据。
echo c > /proc/sysrq-trigger
或者按这个组合按键: Alt+SysRq+c
通过上面的操作,你的系统会立刻崩溃。不出意外的话,系统很快就会重启,然后在/var/crash这个目录下我们就可以找到转储的crash镜像。
到这里,利用kdump进行Linux内核转储的实验就结束了,比起Kdump Tutorial里的步骤简单很多,这都是Ubuntu的功劳。
使用Crash分析转储文件
接下来我们要面对的是如何分析这个crash文件。这里还有一个教程,为了叙述方便,我把它叫做Crash Tutorial。Crash Tutorial主要介绍在Open SUSE和CentOS下如何利用crash工具来分析转储文件,这与Ubuntu还是有点差别的。在上述两个发行版里,kdump生成的crash镜像文件是vmcore,这个文件可以用直接拿来用crash工具分析。Ubuntu提供了一个叫做Apport的工具,Apport用于收集崩溃时所有OS认为有用的信息,并把它们打成一个包,就是上面看到的linux-image-2.6.32-25-generic.0.crash,我们需要的vmcore就在这个包里。下面这个命令用于解包:
apport-unpack /var/crash/linux-image-2.6.32-25-generic.0.crash ~/tmp
我们把crash压缩包解到~/tmp中:
得到vmcore之后,我们还不能立刻进行分析,crash工具需要内核调试信息dbgsym才可以工作。我们可以先看看/usr/lib下有没有debug目录,如果没有,则需要下载安装,下载的地址在这里。注意,下载前先用uname -r命令确定当前内核的确切版本号,dbgsym的版本一定要和内核版本完全匹配才可以。
安装好dbgsym之后,我们就可以使用crash来分析vmcore了,命令如下:
crash /usr/lib/debug/boot/vmlinux-2.6.32-25-generic ~/tmp/VmCore
在crash里,我们可以用bt查看内核崩溃时的call trace:
详细的crash用法大家可以参考Crash Tutorial,或者用Google搜索一下相关资料。
注:
1. 本文采用的操作系统环境是 Kubuntu 10.04,在Ubuntu 10.04下实验应该同样是没有问题的。
2. 我有用过Ubuntu 10.10来实验kdump,但是很不幸,capture kernel没有跑起来,如果大家有在Ubuntu 10.10下的成功经验,麻烦告诉我。