JavaScript is required to for searching.
跳过导航链接
退出打印视图
DTrace 用户指南     Oracle Solaris 10 8/11 Information Library (简体中文)
search filter icon
search icon

文档信息

前言

1.  简介

2.  DTrace 基础知识

3.  使用 D 语言编写脚本

4.  使用 DTrace

性能监视

使用 sysinfo 提供器检查性能问题

跟踪用户进程

使用 copyin() 和 copyinstr() 子例程

避免错误

消除 dtrace 干扰

syscall 提供器

ustack() 操作

pid 提供器

用户函数边界跟踪

跟踪任意指令

匿名跟踪

匿名启用

声明匿名状态

匿名跟踪示例

推理跟踪

推理接口

创建推理

使用推理

提交推理

放弃推理

推理示例

索引

性能监视

多个 DTrace 提供器实现了与现有的性能监视工具对应的探测器:

您可以使用 DTrace 工具来提取与捆绑的工具所提供的信息相同的信息,但具有更大的灵活性。DTrace 工具可以提供在探测器触发时可获得的任何内核信息。DTrace 工具使得您能够接收诸如进程标识、线程标识和栈跟踪之类的信息。

使用 sysinfo 提供器检查性能问题

sysinfo 提供器实现了与 sys 内核统计信息相对应的探测器。这些统计信息为系统监视实用程序(例如 mpstat)提供了输入。sysinfo 提供器探测器在名为 kstat 的 sys 递增前的那一刻触发。下面的列表介绍了 sysinfo 提供器提供的探测器。

bawrite

要将缓冲区异步写出到设备中时将触发的探测器。

bread

从设备中实际读取缓冲区时将触发的探测器。bread 在从设备中请求缓冲区之后,但在阻塞暂挂的请求完成之前触发。

bwrite

要将缓冲区写出(无论同步或异步)到设备中时将触发的探测器。

cpu_ticks_idle

定期系统时钟已确定 CPU 处于空闲时将触发的探测器。请注意,此探测器在系统时钟的上下文中触发,所以将在运行系统时钟的 CPU 中触发。cpu_t 参数 (arg2) 指示已被认为处于空闲状态的 CPU。

cpu_ticks_kernel

定期系统时钟已确定 CPU 正在内核中执行时将触发的探测器。此探测器在系统时钟的上下文中触发,所以将在运行系统时钟的 CPU 中触发。cpu_t 参数 (arg2) 指示 CPU 已被认为正在内核中执行。

cpu_ticks_user

定期系统时钟已确定 CPU 正在用户模式下执行时将触发的探测器。此探测器在系统时钟的上下文中触发,所以将在运行系统时钟的 CPU 中触发。cpu_t 参数 (arg2) 指示 CPU 已被认为正在用户模式下运行。

cpu_ticks_wait

定期系统时钟已确定 CPU 处于空闲状态,但一些线程正在等待 CPU 中的 I/O 时将触发的探测器。此探测器在系统时钟的上下文中触发,所以将在运行系统时钟的 CPU 中触发。cpu_t 参数 (arg2) 指示已被认为在等待 I/O 的 CPU。

idlethread

CPU 进入空闲循环时将触发的探测器。

intrblk

中断线程阻塞时将触发的探测器。

inv_swtch

强制正在运行的线程被迫放弃 CPU 时将触发的探测器。

lread

逻辑上从设备中读取缓冲区时将触发的探测器。

lwrite

逻辑上将缓冲区写入设备时将触发的探测器。

modload

装入内核模块时将触发的探测器。

modunload

卸载内核模块时将触发的探测器。

msg

进行 msgsnd(2) 或 msgrcv(2) 系统调用(但在执行消息队列操作之前)时将触发的探测器。

mutex_adenters

尝试获取已拥有的自适应锁定时将触发的探测器。如果此探测器触发,则 lockstat 提供器的 adaptive-block 和 adaptive-spin 探测器中的一个也会触发。

namei

尝试在文件系统中进行名称查找时将触发的探测器。

nthreads

创建线程时将触发的探测器。

phread

要执行原始 I/O 读取时将触发的探测器。

phwrite

要执行原始 I/O 写入时将触发的探测器。

procovf

由于系统缺乏进程表项而无法创建新进程时将触发的探测器。

pswitch

CPU 从执行某个线程切换到执行另一个线程时将触发的探测器。

readch

每次成功读取后,但在将控制权返回给执行该读取的线程之前将触发的探测器。读取可以通过 read(2)、readv(2) 或 pread(2) 系统调用进行。arg0 包含已成功读取的字节数。

rw_rdfails

每次尝试对读取者或写入者进行读锁定但该锁由某个写入者持有或者是某个写入者所需要的时,将触发的探测器。如果此探测器触发,则 lockstat 提供器的 rw-block 探测器也将触发。

rw_wrfails

每次尝试对读取者或写入者进行写锁定但该锁由多个读取者或另一写入者持有时,将触发的探测器。如果此探测器触发,则 lockstat 提供器的 rw-block 探测器也将触发。

sema

执行 semop(2) 系统调用(但在执行任何信号操作之前)时将触发的探测器。

sysexec

执行 exec(2) 系统调用时将触发的探测器。

sysfork

执行 fork(2) 系统调用时将触发的探测器。

sysread

每次执行 read、readv 或 pread 系统调用时将触发的探测器。

sysvfork

执行 vfork(2) 系统调用时将触发的探测器。

syswrite

执行 write(2)、writev(2) 或 pwrite(2) 系统调用时将触发的探测器。

trap

发生处理器陷阱时将触发的探测器。请注意,一些处理器(特别是 UltraSPARC 变体)通过不会引起此探测器触发的机制处理一些轻量级陷阱。

ufsdirblk

从 UFS 文件系统中读取目录块时将触发的探测器。有关 UFS 的详细信息,请参见 ufs(7FS)。

ufsiget

检索 inode 时将触发的探测器。有关 UFS 的详细信息,请参见 ufs(7FS)。

ufsinopage

可重用不包含任何关联数据页的内核 inode 之后将触发的探测器。有关 UFS 的详细信息,请参见 ufs(7FS)。

ufsipage

可重用包含任何关联数据页的内核 inode 之后将触发的探测器。在将关联的数据页刷新到磁盘之后将触发此探测器。有关 UFS 的详细信息,请参见 ufs(7FS)。

wait_ticks_io

定期系统时钟已确定 CPU 处于空闲状态,但一些线程正在等待 CPU 中的 I/O 时将触发的探测器。此探测器在系统时钟的上下文中触发,所以将在运行系统时钟的 CPU 中触发。cpu_t 参数 (arg2) 指示被描述为在等待 I/O 的 CPU。wait_ticks_io 与 cpu_ticks_wait 之间没有语义差别;wait_ticks_io 因为历史原因而单独存在。

writech

每次成功写入后,但在将控制返回到执行该写入的线程之前将触发的探测器。写入可以通过 write、writev 或 pwrite 系统调用进行。arg0 包含已成功写入的字节数。

xcalls

要进行交叉调用时将触发的探测器。交叉调用是一个 CPU 请求另一个 CPU 的即时工作的操作系统机制。

示例 4-1 将 quantize 聚合函数与 sysinfo 探测器一起使用

quantize 聚合函数显示其参数的二次方频数分布条形图。下面的示例使用 quantize 函数来确定系统上的所有进程在 10 秒的时间段内执行的 read 调用的大小。sysinfo 探测器的 arg0 参数指定统计信息的递增量。对于大多数 sysinfo 探测器,该值为 1。readch 和 writech 探测器是两个例外。对于这两个探测器,arg0 参数分别设置为读取或写入的实际字节数。

# cat -n read.d
   1  #!/usr/sbin/dtrace -s
   2  sysinfo:::readch
   3  {
   4     @[execname] = quantize(arg0);
   5  }
   6
   7  tick-10sec
   8  {
   9     exit(0);
  10  }

# dtrace -s read.d
dtrace: script 'read.d' matched 5 probes
CPU        ID                    FUNCTION:NAME
  0     36754                      :tick-10sec

  bash
         value  ---------- Distribution ---------- count
             0 |                                   0
             1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 13
             2 |                                   0

  file
         value  ---------- Distribution ---------- count
            -1 |                                   0
             0 |                                   2
             1 |                                   0
             2 |                                   0
             4 |                                   6
             8 |                                   0
            16 |                                   0
            32 |                                   6
            64 |                                   6
           128 |@@                                 16
           256 |@@@@                               30
           512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      199
          1024 |                                   0
          2048 |                                   0
          4096 |                                   1
          8192 |                                   1
         16384 |                                   0

  grep
         value  ---------- Distribution ---------- count
            -1 |                                   0
             0 |@@@@@@@@@@@@@@@@@@@                99
             1 |                                   0
             2 |                                   0
             4 |                                   0
             8 |                                   0
            16 |                                   0
            32 |                                   0
            64 |                                   0
           128 |                                   1
           256 |@@@@                               25
           512 |@@@@                               23
          1024 |@@@@                               24
          2048 |@@@@                               22
          4096 |                                   4
          8192 |                                   3
         16384 |                                   0

示例 4-2 查明交叉调用的源头

在本例中,请考虑 mpstat(1M) 命令的以下输出:

CPU minf mjf xcal  intr ithr  csw icsw migr smtx  srw syscl  usr sys  wt idl
  0 2189   0 1302    14    1  215   12   54   28    0 12995   13  14   0  73
  1 3385   0 1137   218  104  195   13   58   33    0 14486   19  15   0  66
  2 1918   0 1039    12    1  226   15   49   22    0 13251   13  12   0  75
  3 2430   0 1284   220  113  201   10   50   26    0 13926   10  15   0  75

xcal 和 syscl 列中的值异常高,表明性能可能被浪费。系统相对空闲并且没有花费异常多的时间等待 I/O。xcal 列中的数字是按比例缩放的每秒数值,是从 sys kstat 的 xcalls 字段读取的。要查看哪些可执行文件是造成交叉调用的原因,请输入以下 dtrace 命令:

# dtrace -n 'xcalls {@[execname] = count()}'
dtrace: description 'xcalls ' matched 3 probes
^C
  find                                                   2
  cut                                                    2
  snmpd                                                  2
  mpstat                                                22
  sendmail                                             101
  grep                                                 123
  bash                                                 175
  dtrace                                               435
  sched                                                784
  xargs                                              22308
  file                                               89889
#

该输出表明,大多数交叉调用发自 file(1) 和 xargs(1) 进程。您可以通过 pgrep(1) 和 ptree(1) 命令查明这些进程。

# pgrep xargs
15973
# ptree 15973
204   /usr/sbin/inetd -s
  5650  in.telnetd
    5653  -sh
      5657  bash
        15970 /bin/sh ./findtxt configuration
          15971 cut -f1 -d:
            15973 xargs file
              16686 file /usr/bin/tbl /usr/bin/troff /usr/bin/ul /usr/bin/vgrind /usr/bin/catman

该输出表明,xargs 和 file 命令构成了某个定制用户 shell 脚本的一部分。要定位该脚本,您可以执行以下命令:

# find / -name findtxt
/usrs1/james/findtxt
# cat /usrs1/james/findtxt
#!/bin/sh
find / -type f | xargs file | grep text | cut -f1 -d: > /tmp/findtxt$$
cat /tmp/findtxt$$ | xargs grep $1
rm /tmp/findtxt$$
#

该脚本同时运行许多进程。大量的进程间通信通过管道进行。管道的数量使得脚本成为资源密集型的。该脚本尝试查找系统上的每个文本文件,然后搜索每个文件来查找特定的文本。