通过前面的学习,你现在可能已经跃跃欲试了。本文接下来的部分,将以 kdump 为例子,向大家演示如何设置系统、如何产生内存转储文件以及如何对内存转储文件进行分析。
如前面所述,支持 kdump 的系统使用两个内核进行工作。目前一些发行版,如 RedHat 和 SUSE 的 Linux 都已经编译并设置好这两个内核。如果你使用其他发行版的 Linux 或者想自己编译内核支持 kdump,那么可以根据如下介绍进行。
使用 root 用户登录系统。 使用 wget 从 Internet 上下载 kexec。 wget kexec-tools.tar.gz解压并安装 kexec 到系统中。 # tar xvpzf kexec-tools.tar.gz # cd kexec-tools-VERSION # ./configure # make && make install
在 "Processor type and features."选项中启用"kexec system call"。 CONFIG_KEXEC=y
在"Filesystem" -> "Pseudo filesystems." 中启用"sysfs file system support"。 CONFIG_SYSFS=y
在"Kernel hacking."中启用"Compile the kernel with debug info"。 CONFIG_DEBUG_INFO=Y
在"Processor type and features"中启用"kernel crash dumps"。 CONFIG_CRASH_DUMP=y
在"Filesystems" -> "Pseudo filesystems"中启用"/proc/vmcore support"。 CONFIG_PROC_VMCORE=y
Linux 内核支持多种 CPU 架构,这里只介绍捕捉内核在 i386 下的配置
在"Processor type and features"中启用高端内存支持。 CONFIG_HIGHMEM64G=y在"Processor type and features"中关闭多处理器支持。 CONFIG_SMP=n
在"Processor type and features"中启用"Build a relocatable kernel"。 CONFIG_RELOCATABLE=y
在"Processor type and features"->"Physical address where the kernel is loaded"中,为内核设置一个加载起始地址。在大多数的机器上,16M 是一个合适的值。 CONFIG_PHYSICAL_START=0x1000000
编译系统内核和捕捉内核。 将重新编译好的内核添加到启动引导中,注意不要将捕捉内核添加到启动引导菜单中。 给系统内核添加启动参数"crashkernel=Y@X",这里,Y 是为 dump 捕捉内核保留的内存,X 是保留部分内存的开始位置。在 i386 的机器上,设置"crashkernel=64M@16M"。 重启机器,在启动菜单中选择新添加的启动项,启动新的系统内核。
在系统内核引导完成后,需要将捕捉内核加载到内存中。使用 kexec 工具将捕捉内核加载到内存:
# kexec -p <dump-capture-kernel-bzImage> \ --initrd=<initrd-for-dump-capture-kernel> \ --append="root=<root-dev> <arch-specific-options>"在捕捉内核被加载进入内存后,如果系统崩溃开关被触发,则系统会自动切换进入捕捉内核。触发系统崩溃的开关有 panic(),die(),die_nmi() 内核函数和 sysrq 触发事件,可以使用其中任意的一个来触发内核崩溃。不过,在让内核崩溃之前,我们还需要做一些安装设置。
Crash 目前的最新的版本是 5.0.0, 你可以从它的官方网站下载最新的版本。下载完成后对其进行解压安装。
# tar -zvxf crash-5.0.0.tar.gz # cd crash-5.0.0 # ./configure # make &&make install现在已经设置好 Kdump 和 crash,现在可以使用前面介绍的系统崩溃开关中的任意一个来引发系统崩溃来生成一个内存转储文件,并可以使用 crash 对其进行分析。
首先,触发系统崩溃,这里使用 sysrq 触发事件。
# echo c > /proc/sysrq-trigger紧接着,系统会自动启动捕捉内核。待完全启动进入捕捉内核后,通过以下命令保存内存转储文件。
# cp /proc/vmcore mydumpfile将在当前目录生成一个 mydumpfile 文件。
现在有了一个内存转储文件,接下来使用 crash 对其进行分析
# crash vmlinux mydumpfile这里 vmlinux 是带调试信息的内核。如果一切正常,将会进入到 crash 中,如图 1 所示。
图 1. crash 命令提示符
在该提示符下,可以执行 crash 的内部命令。通过 crash 的内部命令,可以查看寄存器的值、函数的调用堆栈等信息。在图 2 中,显示了执行 bt命令后得到的函数调用的堆栈信息。
图 2. 函数调用堆栈信息
crash 使用 gdb 作为它的内部引擎,crash 中的很多命令和语法都与 gdb 相同。如果你曾经使用过 gdb,就会发现 crash 并不是很陌生。如果想获得 crash 更多的命令和相关命令的详细说明,可以使用 crash 的内部命令 help来获取。