27.5.使用 DTrace

DTrace 脚本由一个或多个 探针(probes) 组成,每个探针都是一个可被监控的点,并且与一个动作关联。每当探针的条件满足时,关联的动作就会被执行。例如,动作可能发生在文件被打开、进程启动或代码行执行时。动作可以记录信息或修改上下文变量。上下文变量的读写允许探针共享信息,从而协作分析不同事件之间的关联。

要查看所有探针,管理员可以执行以下命令:

# dtrace -l | more

每个探针都有一个 ID、一个 PROVIDER(例如 dtracefbt)、一个 MODULE 和一个 FUNCTION NAME。有关此命令的更多信息,请参考 dtrace(1)

本节的示例概述了如何使用 DTrace Toolkit 中两个完全支持的脚本:hotkernelprocsystime

hotkernel 脚本用于识别消耗最多内核时间的函数。运行示例如下:

# cd /usr/local/share/dtrace-toolkit
# ./hotkernel
Sampling... Hit Ctrl-C to end.

按 Ctrl+C 停止执行。脚本结束后,会显示内核函数及其时间信息,并按时间升序排序:

kernel`_thread_lock_flags                                   2   0.0%
0xc1097063                                                  2   0.0%
kernel`sched_userret                                        2   0.0%
kernel`kern_select                                          2   0.0%
kernel`generic_copyin                                       3   0.0%
kernel`_mtx_assert                                          3   0.0%
kernel`vm_fault                                             3   0.0%
kernel`sopoll_generic                                       3   0.0%
kernel`fixup_filename                                       4   0.0%
kernel`_isitmyx                                             4   0.0%
kernel`find_instance                                        4   0.0%
kernel`_mtx_unlock_flags                                    5   0.0%
kernel`syscall                                              5   0.0%
kernel`DELAY                                                5   0.0%
0xc108a253                                                  6   0.0%
kernel`witness_lock                                         7   0.0%
kernel`read_aux_data_no_wait                                7   0.0%
kernel`Xint0x80_syscall                                     7   0.0%
kernel`witness_checkorder                                   7   0.0%
kernel`sse2_pagezero                                        8   0.0%
kernel`strncmp                                              9   0.0%
kernel`spinlock_exit                                       10   0.0%
kernel`_mtx_lock_flags                                     11   0.0%
kernel`witness_unlock                                      15   0.0%
kernel`sched_idletd                                       137   0.3%
0xc10981a5                                              42139  99.3%

该脚本也支持内核模块。使用 -m 选项运行:

# ./hotkernel -m
Sampling... Hit Ctrl-C to end.
^C
MODULE                                                  COUNT   PCNT
0xc107882e                                                  1   0.0%
0xc10e6aa4                                                  1   0.0%
0xc1076983                                                  1   0.0%
0xc109708a                                                  1   0.0%
0xc1075a5d                                                  1   0.0%
0xc1077325                                                  1   0.0%
0xc108a245                                                  1   0.0%
0xc107730d                                                  1   0.0%
0xc1097063                                                  2   0.0%
0xc108a253                                                 73   0.0%
kernel                                                    874   0.4%
0xc10981a5                                             213781  99.6%

procsystime 脚本捕获并打印指定进程 IDPID)或进程名称的系统调用时间。例如,启动一个新的 /bin/csh 实例后运行:

# ./procsystime -n csh
Tracing... Hit Ctrl-C to end...
^C

Elapsed Times for processes csh,

         SYSCALL          TIME (ns)
          getpid               6131
       sigreturn               8121
           close              19127
           fcntl              19959
             dup              26955
         setpgid              28070
            stat              31899
       setitimer              40938
           wait4              62717
       sigaction              67372
     sigprocmask             119091
    gettimeofday             183710
           write             263242
          execve             492547
           ioctl             770073
           vfork            3258923
      sigsuspend            6985124
            read         3988049784

如上所示,read(2) 系统调用花费时间最长,而 getpid(2) 花费时间最短。

最后更新于