Crash分析过程:
Linux内核(以下简称内核)是一个不与特定进程相关的功能集合,内核的代码很难轻易的在调试器中执行和跟踪。开发者认为,内核如果发生了错误,就不应该继续运行。因此内核发生错误时,它的行为通常被设定为系统崩溃,机器重启。基于动态存储器的电气特性,机器重启后,上次错误发生时的现场会遭到破坏,这使得查找内核的错误变得异常困难。
内核社区和一些商业公司为此开发了很多种调试技术和工具,希望可以让内核的调试变得简单。其中一种是单步跟踪调试方法,即使用代码调试器,一步步的跟踪执行的代码,通过查看变量和寄存器的值来分析错误发生的原因。这一类的调试器有 gdb,kdb, kgdb。另一种方法是在系统崩溃时,将内存保存起来,供事后进行分析。多数情况下,单步调式跟踪可以满足需求,但是单步跟踪调试也有缺点。如遇到如下几种情况时:
- 错误发生在客户的机器上。
- 错误发生在很关键的生产机器上。
- 错误很难重现。
单步调试跟踪方法将无能为力。对于这几种情况,在内核发生错误并崩溃的时候,将内存转储起来供事后分析就显得尤为重要。
当系统发生奔溃时,收集里边的coredump文件,找到对应版本的vmlinux,及时收集log信息备用继续分析。例如图:
使用的是crash 6.0.5版本的,
分析内存转储文件。现在有了一个内存转储文件,接下来使用 crash 对其进行分析
# crash vmlinux cdump_1_s1w-eng2.3.5NS1.512313test-keys_2012731101554.elf |
这里 vmlinux是带调试信息的内核。
PANIC向我们提示了可能出错的地方。
使用bt命令查看最后的栈信息:
图 1. crash 命令提示符
在该提示符下,可以执行 crash的内部命令。通过 crash的内部命令,可以查看寄存器的值、函数的调用堆栈等信息。在图中,显示了执行bt命令后得到的函数调用的堆栈信息。
图 2.函数调用堆栈信息
crash使用 gdb作为它的内部引擎,crash中的很多命令和语法都与 gdb相同。如果你曾经使用过 gdb,就会发现 crash并不是很陌生。如果想获得 crash更多的命令和相关命令的详细说明,可以使用 crash的内部命令help
来获取。
分析步骤:
通过sym地址分析bt中保存的数据,发现他是从最底层到最顶层逐次调用的。分析log找到相应信息如下:
相应参考信息:http://people.redhat.com/anderson/crash_whitepaper/#COMMAND_SET