本章介绍用于事后提取以及处理 DTrace 使用者的内核中数据的 DTrace 工具。在发生系统崩溃时,使用 DTrace 记录的信息可能会提供导致系统故障的根本原因的重要线索。可以通过系统故障转储来提取和处理 DTrace 数据,以帮助您了解致命的系统故障。通过将 DTrace 的这些事后功能与其环形缓冲的缓冲区策略结合(请参见第 11 章),DTrace 可用作商用飞机上的黑匣子飞行数据记录器的操作系统模拟程序。
要从特定故障转储中提取 DTrace 数据,应首先在相关的故障转储中运行 Solaris 模块调试器 mdb(1)。包含 DTrace 功能的 MDB 模块将自动装入。要了解有关 MDB 的更多信息,请参阅《Solaris 模块调试器指南》。
要从 DTrace 使用者中提取 DTrace 数据,必须首先运行 ::dtrace_state MDB dcmd 来确定相关的 DTrace 使用者:
> ::dtrace_state ADDR MINOR PROC NAME FILE ccaba400 2 - <anonymous> - ccab9d80 3 d1d6d7e0 intrstat cda37078 cbfb56c0 4 d71377f0 dtrace ceb51bd0 ccabb100 5 d713b0c0 lockstat ceb51b60 d7ac97c0 6 d713b7e8 dtrace ceb51ab8 |
此命令显示 DTrace 状态结构表。表的每一行由以下信息组成:
状态结构的地址
与 dtrace(7D) 设备关联的次要设备编号
对应于 DTrace 使用者的进程结构的地址
DTrace 使用者的名称(对于匿名使用者,则为 <anonymous>)
对应于已打开 dtrace(7D) 设备的文件结构的名称
要获取有关特定 DTrace 使用者的详细信息,请将其进程结构的地址指定到 ::ps dcmd:
> d71377f0::ps S PID PPID PGID SID UID FLAGS ADDR NAME R 100647 100642 100647 100638 0 0x00004008 d71377f0 dtrace |
确定相关的使用者之后,可以通过将状态结构的地址指定到 ::dtrace dcmd 来检索对应于任何未使用的缓冲区的数据。以下示例显示了在使用操作 trace(execname) 匿名启用 syscall:::entry 时,::dtrace dcmd 的输出:
> ::dtrace_state ADDR MINOR PROC NAME FILE cbfb7a40 2 - <anonymous> - > cbfb7a40::dtrace CPU ID FUNCTION:NAME 0 344 resolvepath:entry init 0 16 close:entry init 0 202 xstat:entry init 0 202 xstat:entry init 0 14 open:entry init 0 206 fxstat:entry init 0 186 mmap:entry init 0 186 mmap:entry init 0 186 mmap:entry init 0 190 munmap:entry init 0 344 resolvepath:entry init 0 216 memcntl:entry init 0 16 close:entry init 0 202 xstat:entry init 0 14 open:entry init 0 206 fxstat:entry init 0 186 mmap:entry init 0 186 mmap:entry init 0 186 mmap:entry init 0 190 munmap:entry init ... |
::dtrace dcmd 采用与 dtrace(1M) 相同的方法处理错误:如果使用者正在执行时遇到删 除、错误、推理删除或类似问题,::dtrace 将发出一条对应于 dtrace(1M) 消息的消息。
::dtrace 显示事件的顺序在给定 CPU 中始终为从最旧到最新。CPU 缓冲区本身按照数字顺序显示。如果需要对不同 CPU 中的事件进行排序,请跟踪 timestamp 变量。
可以通过将 -c 选项指定到 ::dtrace,来仅显示特定 CPU 的数据:
> cbfb7a40::dtrace -c 1 CPU ID FUNCTION:NAME 1 14 open:entry init 1 206 fxstat:entry init 1 186 mmap:entry init 1 344 resolvepath:entry init 1 16 close:entry init 1 202 xstat:entry init 1 202 xstat:entry init 1 14 open:entry init 1 206 fxstat:entry init 1 186 mmap:entry init ... |
请注意,::dtrace 仅处理内核中的 DTrace 数据。通过内核使用并通过 dtrace(1M) 或其他方法处理的数据不可以使用 ::dtrace 进行处理。要确保在出现故障时可以使用大多数的数据,请使用环形缓冲区的缓冲策略。有关缓冲区策略的更多信息,请参见第 11 章。
以下示例创建一个非常小 (16K) 的环形缓冲区,并记录所有系统调用以及使这些调用执行以下操作的进程:
# dtrace -P syscall'{trace(curpsinfo->pr_psargs)}' -b 16k -x bufpolicy=ring dtrace: description 'syscall:::entry' matched 214 probes |
查看运行上述命令时所采用的故障转储将生成与以下示例类似的输出:
> ::dtrace_state ADDR MINOR PROC NAME FILE cdccd400 3 d15e80a0 dtrace ced065f0 > cdccd400::dtrace CPU ID FUNCTION:NAME 0 139 getmsg:return mibiisa -r -p 25216 0 138 getmsg:entry mibiisa -r -p 25216 0 139 getmsg:return mibiisa -r -p 25216 0 138 getmsg:entry mibiisa -r -p 25216 0 139 getmsg:return mibiisa -r -p 25216 0 138 getmsg:entry mibiisa -r -p 25216 0 139 getmsg:return mibiisa -r -p 25216 0 138 getmsg:entry mibiisa -r -p 25216 0 139 getmsg:return mibiisa -r -p 25216 0 138 getmsg:entry mibiisa -r -p 25216 0 17 close:return mibiisa -r -p 25216 ... 0 96 ioctl:entry mibiisa -r -p 25216 0 97 ioctl:return mibiisa -r -p 25216 0 96 ioctl:entry mibiisa -r -p 25216 0 97 ioctl:return mibiisa -r -p 25216 0 96 ioctl:entry mibiisa -r -p 25216 0 97 ioctl:return mibiisa -r -p 25216 0 96 ioctl:entry mibiisa -r -p 25216 0 97 ioctl:return mibiisa -r -p 25216 0 16 close:entry mibiisa -r -p 25216 0 17 close:return mibiisa -r -p 25216 0 124 lwp_park:entry mibiisa -r -p 25216 1 68 access:entry mdb -kw 1 69 access:return mdb -kw 1 202 xstat:entry mdb -kw 1 203 xstat:return mdb -kw 1 14 open:entry mdb -kw 1 15 open:return mdb -kw 1 206 fxstat:entry mdb -kw 1 207 fxstat:return mdb -kw 1 186 mmap:entry mdb -kw ... 1 13 write:return mdb -kw 1 10 read:entry mdb -kw 1 11 read:return mdb -kw 1 12 write:entry mdb -kw 1 13 write:return mdb -kw 1 96 ioctl:entry mdb -kw 1 97 ioctl:return mdb -kw 1 364 pread64:entry mdb -kw 1 365 pread64:return mdb -kw 1 366 pwrite64:entry mdb -kw 1 367 pwrite64:return mdb -kw 1 364 pread64:entry mdb -kw 1 365 pread64:return mdb -kw 1 38 brk:entry mdb -kw 1 39 brk:return mdb -kw > |
请注意,CPU 1 的最新记录包括由 mdb -kw 进程进行的一系列 write(2) 系统调用。此结果可能与系统故障的原因有关,因为在使用 -k 和 -w 选项运行时,用户可以使用 mdb(1) 修改正在运行的内核数据或文本。在此情况下,DTrace 数据至少提供了一种让人关注的调查方法(如果不是故障的根本原因)。