Solaris 动态跟踪指南

第 36 章 匿名跟踪

本章介绍匿名跟踪,匿名跟踪是不与任何 DTrace 使用者关联的跟踪。在没有可以运行的 DTrace 进程情况下才使用匿名跟踪。匿名跟踪通常用于允许设备驱动程序开发者调试和跟踪系统引导期间发生的活动。任何可以交互执行的跟踪都可以匿名执行。但是,仅有超级用户才可以创建匿名启用,任何时候仅可以存在一个匿名启用。

匿名启用

要创建匿名启用,请将 -A 选项与指定需要的探测器、谓词、操作和选项的 dtrace(1M) 调用结合使用。dtrace 会将一系列代表您请求的驱动程序属性添加到 dtrace(7D) 驱动程序的配置文件(通常为 /kernel/drv/dtrace.conf)中。这些属性将由 dtrace(7D) 驱动程序在装入时读取。该驱动程序将使用指定的操作启用指定的探测器,并创建与新的启用关联的匿名状态。通常,dtrace(7D) 驱动程序根据需要进行装入,这与充当 DTrace 提供器的任何驱动程序一样。要允许在引导期间跟踪,必须尽早装入 dtrace(7D) 驱动程序。dtrace 针对每个必 需的 DTrace 提供器和 dtrace(7D) 本身,将所需要的 forceload 语句添加至 /etc/system(请参见 system(4))中。

此后,当引导系统时,dtrace(7D) 将发出一条消息,指示已成功处理配置文件。

所有选项都可以使用匿名启用设置,包括缓冲区大小、动态变量大小、推理大小、推理数等。

要删除匿名启用,请将 -A 指定给不包含任何探测器说明的 dtrace

声明匿名状态

在计算机完成引导之后,可以通过指定带有 -a 选项的 dtrace 来声明任何匿名状态。缺省情况下,-a 会声明匿名状态、处理现有数据,然后继续运行。要使用匿名状态,然后退出,请添加 -e 选项。

一旦在内核中使用匿名状态,将无法替换该状态:因为包含该状态的内核内部的缓冲区被重用。如果尝试声明不存在的匿名跟踪状态,则 dtrace 将生成与以下示例类似的消息:


dtrace: could not enable tracing: No anonymous tracing state

如果发生删除或错误,dtrace 将在声明匿名状态时生成相应的消息。对于匿名和非匿名状态,删除消息和错误消息相同。

匿名跟踪示例

以下示例说明了 iprb(7D) 模块中每个探测器的匿名 DTrace 启用:


# dtrace -A -m iprb
dtrace: saved anonymous enabling in /kernel/drv/dtrace.conf
dtrace: added forceload directives to /etc/system
dtrace: run update_drv(1M) or reboot to enable changes
# reboot

重新引导后,dtrace(7D) 将在控制台上列显一条消息,指示正在启用指定的探测器:


  ...
  Copyright 1983-2003 Sun Microsystems, Inc.  All rights reserved.
  Use is subject to license terms.
  NOTICE: enabling probe 0 (:iprb::)
  NOTICE: enabling probe 1 (dtrace:::ERROR)
  configuring IPv4 interfaces: iprb0.
  ...

重新引导计算机后,可以通过指定带有 -a 选项的 dtrace 来使用匿名状态:


# dtrace -a
  CPU     ID                    FUNCTION:NAME
    0  22954                      _init:entry 
    0  22955                     _init:return 
    0  22800                  iprbprobe:entry 
    0  22934          iprb_get_dev_type:entry 
    0  22935         iprb_get_dev_type:return 
    0  22801                 iprbprobe:return 
    0  22802                 iprbattach:entry 
    0  22874               iprb_getprop:entry 
    0  22875              iprb_getprop:return 
    0  22934          iprb_get_dev_type:entry 
    0  22935         iprb_get_dev_type:return 
    0  22870             iprb_self_test:entry 
    0  22871            iprb_self_test:return 
    0  22958            iprb_hard_reset:entry 
    0  22959           iprb_hard_reset:return 
    0  22862       iprb_get_eeprom_size:entry 
    0  22826              iprb_shiftout:entry 
    0  22828            iprb_raiseclock:entry 
    0  22829           iprb_raiseclock:return 
  ...

以下示例仅适用于通过 iprbattach() 调用的那些函数。在编辑器中,键入以下脚本并将其保存在名为 iprb.d 的文件中。

fbt::iprbattach:entry
{
	self->trace = 1;
}

fbt:::
/self->trace/
{}

fbt::iprbattach:return
{
	self->trace = 0;
}

运行以下命令清除驱动器配置文件中先前的设置,安装新的匿名跟踪请求,然后重新引导:


# dtrace -AFs iprb.d
dtrace: cleaned up old anonymous enabling in /kernel/drv/dtrace.conf
dtrace: cleaned up forceload directives in /etc/system
dtrace: saved anonymous enabling in /kernel/drv/dtrace.conf
dtrace: added forceload directives to /etc/system
dtrace: run update_drv(1M) or reboot to enable changes
# reboot

重新引导后,dtrace(7D) 将在控制台上列显一条不同的消息,指示稍微不同的启用项:


  ...
  Copyright 1983-2003 Sun Microsystems, Inc.  All rights reserved.
  Use is subject to license terms.
  NOTICE: enabling probe 0 (fbt::iprbattach:entry)
  NOTICE: enabling probe 1 (fbt:::)
  NOTICE: enabling probe 2 (fbt::iprbattach:return)
  NOTICE: enabling probe 3 (dtrace:::ERROR)
  configuring IPv4 interfaces: iprb0.
  ...

计算机完成引导后,运行带有 -a 选项和 -e 选项的 dtrace 以使用匿名数据,然后退出。


# dtrace -ae
  CPU FUNCTION                                 
    0  -> iprbattach                            
    0    -> gld_mac_alloc                       
    0      -> kmem_zalloc                       
    0        -> kmem_cache_alloc                
    0          -> kmem_cache_alloc_debug        
    0            -> verify_and_copy_pattern     
    0            <- verify_and_copy_pattern     
    0            -> tsc_gethrtime               
    0            <- tsc_gethrtime               
    0            -> getpcstack                  
    0            <- getpcstack                  
    0            -> kmem_log_enter              
    0            <- kmem_log_enter              
    0          <- kmem_cache_alloc_debug        
    0        <- kmem_cache_alloc                
    0      <- kmem_zalloc                       
    0    <- gld_mac_alloc                       
    0    -> kmem_zalloc                         
    0      -> kmem_alloc                        
    0        -> vmem_alloc                      
    0          -> highbit                       
    0          <- highbit                       
    0          -> lowbit                        
    0          <- lowbit                        
    0          -> vmem_xalloc                   
    0            -> highbit                     
    0            <- highbit                     
    0            -> lowbit                      
    0            <- lowbit                      
    0            -> segkmem_alloc               
    0              -> segkmem_xalloc            
    0                -> vmem_alloc              
    0                  -> highbit               
    0                  <- highbit               
    0                  -> lowbit                
    0                  <- lowbit                
    0                  -> vmem_seg_alloc        
    0                    -> highbit             
    0                    <- highbit             
    0                    -> highbit             
    0                    <- highbit             
    0                    -> vmem_seg_create     
  ...