分类:
2009-09-18 11:42:45
kdb 入门 |
级别: 中级 Divya Vikas, 软件工程师, IBM 2008 年 12 月 24 日 kdb 是专门用于执行系统转储映像分析的实用工具。本文将将介绍系统转储分析的基本步骤。 对于基本的转储分析,本文主要解释转储映像。我们将介绍如何从 snap 包中提取相应的文件,接着介绍一种检查转储的系统方法,然后探查引起系统崩溃的根本原因。转储文件和 UNIX ® 文件位于 snap 包的 dump 子目录中。 虽然我们考察的重点是转储映像,但是适当地使用 snap 选项还可以获得有用的信息,这点很重要。更多信息请阅读本文的 General 和 Kernel 小节。 general 目录包括有关系统运行时环境的信息,例如:
kernel 子目录包含了有用的内核信息(进程和内存数据)。
使用 pax 命令从 snap 包中提取文件。
kdb 实用工具检查当前运行系统的操作系统映像,并且与 IBM® AIX® 内核紧密耦合。这是因为它要求使用内核的结构信息来准确地格式化系统转储映像中包含的信息。kdb 为查看和格式化数据结构提供了大量子命令。
kdb 是一个交互式内核调试器。kdb 允许用户控制内核代码的执行(包括内核扩展和设备驱动器),并观察和修改变量和寄存器。它必须由一个特殊的启动映像调用。 kdb 是一个分析系统转储的工具/命令。它用于对系统转储进行事后分析,或用于监视运行中的内核。 kdb 在检查系统转储时通过两个参数调用。第一个参数指定系统映像,而第二个参数指定转储期间系统运行的内核的 UNIX 文件。UNIX 文件必须匹配转储映像(比如,发生崩溃时正在运行的映像)。如果不匹配的话,kdb 将显示一个错误消息并退出。
如果没有使用参数调用,kdb 将检查当前正在运行的系统的映像。
对转储映像调用 kdb 之后,首先使用 stat 子命令检索基本转储状态: kdb 的 stat 子命令提供了正在查看的转储的信息。除了包含日期、时间、版本和发布信息外,还包含转储原因代码。 如果由于系统检测到问题而发起转储,那么 stat 子命令的输出将包含标题为 CRASH INFORMATION 的部分。
这意味着转储原因代码为 300,即 DSI(DATA STORAGE INTERRUPT)。 转储原因代码表示造成崩溃的基本原因。大多数崩溃通常显示的原因代码为 300、400 和 700。
kdb 永远在运行崩溃线程的 CPU 上下文中启动。当调用 kdb 时,显示以下提示: 然而,要切换到另一个 CPU 上下文,可以使用 cpu 子命令:
Machine State save area(MST)包含已保存的 CPU 进程上下文的映像。进程上下文包含通用寄存器、浮点寄存器、特殊用途的寄存器和其他有关重启线程所需的信息。CPU 上的每个处理器都拥有自己的 CSA(当前保存区)指针,指向当线程或中断处理程序由于上下文切换而被中断或交换时使用的 MST。虽然线程是活动的,但是运行线程的处理器的 CSA 将指向当前活动线程的 MST。
prev 和 intpri 字段中的值帮助判断处理器是在运行线程还是在运行中断处理程序。 如果 CPU 正在运行一个线程,该线程可以位于处理上下文或中断上下文中。中断处理程序始终在中断上下文中运行。 处理环境与中断环境之间的主要差别是:当处于中断环境中时,不允许出现任何页面错误。 每个 CPU 都有自己的 MSR,它表示处理器的状态。 dr msr /* dr cmd 用于转储任何寄存器 */ 的内容
在讨论系统转储时,我们只关注在 CPU 中运行的引起系统崩溃的东西。 如果在 MSR 中设置了 PR 位(问题状态),那么 CPU 在用户模式下运行,并且不可能引起系统崩溃。因为用户模式指令没有引起系统崩溃的足够权限。 如果转储原因代码为 300 或 400,我们必须对异常结构进行分析。
我们必须对 mst 输出中的值进行分析。特别要检查 IAR 引用的指令,证实它引起的崩溃类型是 stat 子命令报告的类型。 在 VMM 提供崩溃原因时,vmlog 子命令提供额外的信息。代码 300 转储中显示的 Error ID 是 DSI_PROC,而在代码 400 转储中为 ISI_PROC。Exception DSISR/ISISR,srval,virt addr 包含异常结构中显示的信息。Exception 值是一个内部 VMM 错误代码。
它显示线程的内核模式栈跟踪。 如果没有提供任何参数,则显示当前 CPU 上下文的栈跟踪。 上图显示了 stat 命令的输出。输出显示错误代码为 300,表明这是一个 DSI 崩溃。 上图显示的栈跟踪描述了当 CPU 0 上的某个线程运行 function __memmove 时出现的问题。 mst 子命令的输出表示线程(表示为 prev =0)在启用了所有中断的情况下运行(表示为 intpri =0B)。换句话说,线程正在进程环境中运行。 异常结构的 dsisr 字段由两项组成,DSISR_PROT 和 DSISR_ST。DSISR_PROT 字段表示出现保护违反(protection violation)。DSISR_ST 表示问题与存储操作有关。引起页面错误的数据地址为 0x00(dar 0000000000000000)。 异常结构 dsisr 字段的 DSISR_ST 表示存储操作出了问题。我们希望 IAR 引用某种形式的存储指令。
r7 的当前内容将被存储到内存地址中(向 r3 的当前值加 0x08 得出该地址)。从 mst 子命令的输出可以看到,r3 的当前值是 FFFFFFFFFFFFFFF8,因此向 FFFFFFFFFFFFFFF8 加 0x08 将得到:
这意味着 r7 的当前内容将被保存到地址 0X00。它匹配异常结构中 dar 字段显示的值。 内核地址空间中的第一页虚拟内存可通过内核代码访问,但是被标记为只读。任何对该内存范围执行写操作的尝试将导致保护违反。
在使用 asterix (*) 调用 proc 子命令时,它将以一行摘要显示进程表中的所有活动进程。 当使用进程表地址或 slot 编号调用 proc 子命令时,它将详细显示指定地址或 slot 的格式化进程信息(如果在未使用参数的情况下调用 proc 子命令,它将详细显示当前进程的格式化进程信息)。 当使用 asterix (*) 调用 thread 子命令时,它将以一行摘要显示线程表中的所有活动线程。 当使用线程表地址或 slot 编号调用 thread 子命令时,它将详细显示指定线程的格式化线程信息(如果在未使用参数的情况下调用 thread 子命令,它将详细显示当前线程的格式化线程信息)。 status 子命令列出了所有 CPU 的当前线程和进程的信息。
日志级别可设为 0、1 或 2。这决定将哪种信息记录到日志文件中。值 0 表示禁止记录到日志文件中。值 1 表示只记录在提示时输入的 kdb 命令。值 2 记录 kdb 会话的输入和输出。
查找系统崩溃的根本原因是一个单调乏味的过程,因此了解 kdb 非常有用,它供一种分析系统崩溃的系统方法。通过 kdb,您将能够迅速跟踪导致系统崩溃问题。此外,您还学习到一种很有价值技能,借助它不仅能够节省大量调试时间,还可以了解可以避免系统崩溃的编程实践。最后这点也很重要,这是一种可以快速解决崩溃问题的系统性方法,它将帮助您赢得客户信任。 |