DTrace 脚本由一个或多个 探针(或称为仪器点)组成,每个探针与一个动作相关联。当探针的条件被满足时,相关的动作就会执行。例如,动作可能在文件被打开、进程被启动或一行代码被执行时发生。这个动作可能是记录一些信息或修改上下文变量。上下文变量的读写允许探针共享信息,并协作分析不同事件的关联性。
要查看所有探针,管理员可以执行以下命令:
每个探针都有一个 ID、PROVIDER(如 dtrace 或 fbt)、MODULE 和 FUNCTION NAME。有关该命令的更多信息,请参考 。
本节中的示例概述了如何使用 DTrace 工具包中的两个完全支持的脚本:hotkernel 和 procsystime 脚本。
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()
系统调用使用的时间最少。