27.5.使用 DTrace

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

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

# dtrace -l | more

每个探针都有一个 IDPROVIDER(如 dtrace 或 fbt)、MODULEFUNCTION NAME。有关该命令的更多信息,请参考 dtrace(1)

本节中的示例概述了如何使用 DTrace 工具包中的两个完全支持的脚本: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 脚本捕获并打印给定进程 ID (PID) 或进程名称的系统调用时间使用情况。以下是一个示例,首先启动了一个新的 /bin/csh 实例。然后,执行了 procsystime 并在另一个 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() 系统调用使用了最多的时间(以纳秒为单位),而 getpid() 系统调用使用的时间最少。

最后更新于