Solaris 动态跟踪指南

第 37 章 事后跟踪

本章介绍用于事后提取以及处理 DTrace 使用者的内核中数据的 DTrace 工具。在发生系统崩溃时,使用 DTrace 记录的信息可能会提供导致系统故障的根本原因的重要线索。可以通过系统故障转储来提取和处理 DTrace 数据,以帮助您了解致命的系统故障。通过将 DTrace 的这些事后功能与其环形缓冲的缓冲区策略结合(请参见第 11 章),DTrace 可用作商用飞机上的黑匣子飞行数据记录器的操作系统模拟程序。

要从特定故障转储中提取 DTrace 数据,应首先在相关的故障转储中运行 Solaris 模块调试器 mdb(1)。包含 DTrace 功能的 MDB 模块将自动装入。要了解有关 MDB 的更多信息,请参阅《Solaris 模块调试器指南》

显示 DTrace 使用者

要从 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 使用者的详细信息,请将其进程结构的地址指定到 ::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 数据至少提供了一种让人关注的调查方法(如果不是故障的根本原因)。