通过 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 探测器的存在都将使您快速发现异常监视输出的根本原因。