Solaris 动态跟踪指南

示例

通过 mpstat(1M) 检查以下输出:


CPU minf mjf xcal  intr ithr  csw icsw migr smtx  srw syscl  usr sys  wt idl
 12   90  22 5760   422  299  435   26   71  116   11  1372    5  19  17  60
 13   46  18 4585   193  162  431   25   69  117   12  1039    3  17  14  66
 14   33  13 3186   405  381  397   21   58  105   10   770    2  17  11  70
 15   34  19 4769   109   78  417   23   57  115   13   962    3  14  14  69
 16   74  16 4421   437  406  448   29   77  111    8  1020    4  23  14  59
 17   51  15 4493   139  110  378   23   62  109    9   928    4  18  14  65
 18   41  14 4204   494  468  360   23   56  102    9   849    4  17  12  68
 19   37  14 4229   115   87  363   22   50  106   10   845    3  15  14  67
 20   78  17 5170   200  169  456   26   69  108    9  1119    5  21  25  49
 21   53  16 4817    78   51  394   22   56  106    9   978    4  17  22  57
 22   32  13 3474   486  463  347   22   48  106    9   769    3  17  17  63
 23   43  15 4572    59   34  361   21   46  102   10   947    4  15  22  59

从上面的输出可以总结出 xcal 字段似乎太高,特别是所指定的系统相对空闲程度。mpstat 通过检查 sys 内核统计信息的 xcalls 字段确定 xcal 字段的值。因此,通过启用 xcalls sysinfo 探测器可以轻松地研究此异常,如下例所示:


# dtrace -n xcalls'{@[execname] = count()}'
dtrace: description 'xcalls' matched 4 probes
^C
  dtterm                                                            1
  nsrd                                                              1
  in.mpathd                                                         2
  top                                                               3
  lockd                                                             4
  java_vm                                                          10
  ksh                                                              19
  iCald.pl6+RPATH                                                  28
  nwadmin                                                          30
  fsflush                                                          34
  nsrindexd                                                        45
  in.rlogind                                                       56
  in.routed                                                       100
  dtrace                                                          153
  rpc.rstatd                                                      246
  imapd                                                           377
  sched                                                           431
  nfsd                                                           1227
  find                                                           3767

该输出说明了查找交叉调用的源的位置。一些数量的 find(1) 处理导致大多数交叉调用。以下 D 脚本可用于进一步详细了解该问题:

syscall:::entry
/execname == "find"/
{
	self->syscall = probefunc;
	self->insys = 1;
}

sysinfo:::xcalls
/execname == "find"/
{
	@[self->insys ? self->syscall : "<none>"] = count();
}

syscall:::return
/self->insys/
{
	self->insys = 0;
	self->syscall = NULL;
}

此脚本使用 syscall 提供器将来自 find 的交叉调用归结到特定系统调用。一些交叉调用(如由于页面错误产生的系统调用)可能不是通过系统调用发出。此脚本在这些情况下将列显 "<none>"。运行此脚本将会生成与以下示例类似的输出:


# dtrace -s ./find.d
 dtrace: script './find.d' matched 444 probes
^C
  <none>                                                            2
  lstat64                                                        2433
  getdents64                                                    14873

此输出指示由 find 触发的大多数交叉调用又被 getdents(2) 系统调用触发。进一步的了解取决于您要了解的具体方面。如果要了解为什么 find 进程进行 getdents 调用,可以编写 D 脚本在 find 触发交叉调用时聚集 ustack()。如果要了解为什么 getdents 调用触发交叉调用,可以编写 D 脚本在 find 触发交叉调用时聚集 stack()。无论下一步执行什么,xcalls 探测器的存在都将使您快速发现异常监视输出的根本原因。