# Crash了!其实也没有那么糟糕
在嵌入式Linux系统驱动开发过程中,尤其是内核开发,费了半天劲儿把代码编译进入内核,上电,运行。结果crash了,你说沮丧不沮丧!系统crash了也就意味着编写的程序代码出现了bug。以前觉得crash是对自己的极大的否定,学习了本章之后,觉得也没有那么糟糕。嘿嘿~~
## Kdump + Crash工具
我们先介绍一下Kdump系列工具。Kdump工具是内核转储工具,其核心实现基于Kexec。Kexec工具可以快速启动一个新的内核,它会跳过BIOS或bootloader等引导程序的初始化阶段。此特性可以让系统崩溃时快速切换到一个备份的内核,这样第一个内核的内存就得到保留。在第二个内核中可以对第一个内核产生的崩溃数据继续分析。即当生产内核crash时,快速切换到备份内核,并进行信息收集和转储。Kexec的工作原理如下图所示:
Kdump并非默认安装,毕竟做开发的人员还是占少数,安装步骤如下:
```bash
sudo yum install kexec-toolscrash
```
当触发内核crash后,转储文件存放于 /var/crash 目录,另一个我们在分析使用的文件是vmlinux,即我们在编译内核时生成的文件,我估计需显示函数名,这样就要链接地址与符号名一一对应。
找到上述两个关键文件后,可以使用crash命令来对内核进行分析了。这里对常用子命令做一个介绍:
- bt子命令:输出一个进程的内核栈的函数调用关系,包括所有异常栈的信息;通过本子命令,我们可以追踪到具体crash的函数。将问题定位到具体的行号;
- rd子命令:用来读取内存地址中的值;
- dis子命令:输出反汇编结果。限于我的水平,我是一直没有使用过此命令。在平时工作中,解bug还真没有到这个级别。
在平时的内核开发工作中,最常用的还是分段注释法和打印法。主要原因还是限于水平,编程的项目复杂度较低,错误原因也就是常见的那几项,如空指针传入,数组越界溢出,变量CtrlC,CtrlV时,未及时变更变量名,标号等。
杀鸡不用牛刀,但牛刀我们依然需要掌握。Crash了,我们还是有办法的。