kdump

什么是kdump?

kdump 是一种的基于 kexec 的内核崩溃转储机制,类似飞机的黑匣子,系统一但崩溃,内核无法正常记录信息了,这时kdump将转入带第二个捕获内核,将第二个内核加载的内存中,对第一个内核的信息进行捕获。由于 kdump 利用 kexec 启动捕获内核,绕过了 BIOS,所以第一个内核的内存得以保留。这是内核崩溃转储的本质。
kexec是一个快速启动机制,可以通过已经运行的内核,启动另外一个内核不需要经过bios

kdump原理?

kdump 需要两个不同目的的内核,生产内核和捕获内核。生产内核是捕获内核服务的对像。捕获内核会在生产内核崩溃时启动起来,与相应的 ramdisk 一起组建一个微环境,用以对生产内核下的内存进行收集和转存。

kdump配置和使用
操作系统:centos7.2

安装配置分析工具crash
yum install crash

安装kernel-debuginfo(需要根内核版本一一对应)

1
wget http://debuginfo.centos.org/7/x86_64/kernel-debuginfo-common-x86_64-3.10.0-327.el7.x86_64.rpm
1
2
3
4
wget http://debuginfo.centos.org/7/x86_64/kernel-debuginfo-3.10.0-327.el7.x86_64.rpm
````

下载完成后安装

rpm -ivh kernel-debuginfo-common-x86_64-3.10.0-327.el7.x86_64.rpm kernel-debuginfo-3.10.0-327.el7.x86_64.rpm

1
安装完后确认是否有

/usr/lib/debug/lib/modules/3.10.0-327.el7.x86_64/vmlinux此文件

1
2
3
4
5
6
7
8
9
10
11
12
13

### 配置kdump
可以配置内核崩溃后崩溃日志存到何地

![](https://image-1251900790.cos.ap-chengdu.myqcloud.com/image/kdmup_1.png)

默认是放在本地/var/crash
下图为配置scp,表示将log文件放到192.168.2.100/log 目录,同时key文件目录需要指定
![](https://image-1251900790.cos.ap-chengdu.myqcloud.com/image/kdmup_2.png)

### 测试kdump
配置捕获占用的内存
使用grubby修改grub2.cfg文件

grubby –update-kernel=DEFAULT –args=crashkernel=128M

1
2
3
4
重启服务器  
reboot

启动kdump

systemctl start kdump && systemctl enable kdump

1
2
3
4
ls /boot 会发现生成了一个kdump结尾的文件
![](https://image-1251900790.cos.ap-chengdu.myqcloud.com/image/kdmup_3.png)

执行以下命令让内核crash

echo 1 > /proc/sys/kernel/sysrq
echo c > /proc/sysrq-trigger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
此时系统会立刻失去连接进入捕获内核

开机后

![](https://image-1251900790.cos.ap-chengdu.myqcloud.com/image/kdmup_4.png)
![](https://image-1251900790.cos.ap-chengdu.myqcloud.com/image/kdmup_5.png)

以下参考IBM文档链接见文尾

### crash解析崩溃日志

vmcore-dmesg.txt可以查看错误信息
(1) 错误类型
首先可以在vmcore-dmesg.txt中先查看错误类型,如:
divide error: 0000 [#1] SMP,除数为0造成内核崩溃,由1号CPU触发。
BUG: unable to handle kernel NULL pointer dereference at 000000000000012c,引用空指针。
这样一来就能知道引发内核崩溃的错误类型。

(2) 错误地点
RIP为造成内核崩溃的指令,Call Trace为函数调用栈,通过RIP和Call Trace可以确定函数的调用路径,以及在
哪个函数中的哪条指令引发了错误。

例如RIP为:[``<ffffffff812cdb54>``] ? tcp_enter_loss+0x1d3/0x23b

[``<ffffffff812cdb54>``]是指令在内存中的虚拟地址。
tcp_enter_loss是函数名(symbol)。
0x1d3是这条指令相对于tcp_enter_loss入口的偏移,0x23b是函数编译成机器码后的长度。
这样一来就能确定在哪个函数中引发了错误,以及错误的大概位置。

Call Trace为函数的调用栈,是从下往上看的。可以用来分析函数的调用关系。

### vmcore信息

crash /usr/lib/debug/lib/modules/3.10.0-327.el7.x86_64/vmlinux /var/crash/127.0.0.1-2017-09-20-13:09:30/vmcore

1
2
![](https://image-1251900790.cos.ap-chengdu.myqcloud.com/image/kdmup_6.png)

KERNEL: 系统崩溃时运行的 kernel 文件
DUMPFILE: 内核转储文件
CPUS: 所在机器的 CPU 数量
DATE: 系统崩溃的时间
TASKS: 系统崩溃时内存中的任务数
NODENAME: 崩溃的系统主机名
RELEASE: 和 VERSION: 内核版本号
MACHINE: CPU 架构
MEMORY: 崩溃主机的物理内存
PID:3507表示当崩溃时3507这个bash的进程在操作
PANIC: 崩溃类型,常见的崩溃类型包括:
SysRq (System Request):通常是测试使用。通过 echo c > /proc/sysrq-trigger,就可以触发系统崩溃。
oops:可以看成是内核级的 Segmentation Fault。应用程序如果进行了非法内存访问或执行了非法指令,会得到 Segfault 信号,一般行为是 coredump,应用程序也可以自己截获 Segfault 信号,自行处理。如果内核自己犯了这样的错误,则会弹出 oops 信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

bt(backtrace)
显示内核堆栈信息
![](https://image-1251900790.cos.ap-chengdu.myqcloud.com/image/kdmup_7.png)

如上输出中,以“# 数字”开头的行为调用堆栈,即系统崩溃前内核依次调用的一系列函数,通过这个可以迅速推断内核在何处崩溃。

log - dump system message buffer
log 命令可以打印系统消息缓冲区,从而可能找到系统崩溃的线索。log 命令的截图如下(为节省篇幅,已将部分行省略):

![](https://image-1251900790.cos.ap-chengdu.myqcloud.com/image/kdmup_8.png)

ps 命令用于显示进程的状态,(如图)带 > 标识代表是活跃的进程。ps 命令的截图如下(省略部分行):

![](https://image-1251900790.cos.ap-chengdu.myqcloud.com/image/kdmup_9.png)

dis - disassembling instruction
dis 命令用于对给定地址的内容进行反汇编。dis 命令的截图如下:
![](https://image-1251900790.cos.ap-chengdu.myqcloud.com/image/kdmup_10.png)

参考链接
http://www.361way.com/centos-kdump/3751.html
http://blog.csdn.net/zhangskd/article/details/38084337
https://www.ibm.com/developerworks/cn/linux/l-cn-kdump4/index.html