对于 pid 提供器,最简单的操作模式是作为与 fbt 提供器类似的用户空间。以下示例程序将跟踪通过单个函数产生的所有函数进入和返回。$1 宏变量(命令行中的第一个操作数)是要跟踪的进程的进程 ID。$2 宏变量(命令行中的第二个操作数)是要从中跟踪所有函数调用的函数的名称。
pid$1::$2:entry { self->trace = 1; } pid$1::$2:return /self->trace/ { self->trace = 0; } pid$1:::entry, pid$1:::return /self->trace/ { }
键入以上示例脚本,并将其保存在名为 userfunc.d 的文件中,然后通过 chmod 将其转换为可执行文件。此脚本生成的输出与以下示例类似:
# ./userfunc.d 15032 execute dtrace: script './userfunc.d' matched 11594 probes 0 -> execute 0 -> execute 0 -> Dfix 0 <- Dfix 0 -> s_strsave 0 -> malloc 0 <- malloc 0 <- s_strsave 0 -> set 0 -> malloc 0 <- malloc 0 <- set 0 -> set1 0 -> tglob 0 <- tglob 0 <- set1 0 -> setq 0 -> s_strcmp 0 <- s_strcmp ... |
pid 提供器只能用于已在运行的进程。您可以使用 $target 宏变量(请参见第 15 章)以及 dtrace -c 和 -p 选项来创建和抓取所关注的进程,并使用 DTrace 对其进行检测。例如,以下 D 脚本可用于确定通过特定主题进程对 libc 执行的函数调用的分布:
pid$target:libc.so::entry { @[probefunc] = count(); }
要确定由 date(1) 命令执行的此类调用的分布,请将脚本保存在名为 libc.d 的文件中并执行以下命令:
# dtrace -s libc.d -c date dtrace: script 'libc.d' matched 2476 probes Fri Jul 30 14:08:54 PDT 2004 dtrace: pid 109196 has exited pthread_rwlock_unlock 1 _fflush_u 1 rwlock_lock 1 rw_write_held 1 strftime 1 _close 1 _read 1 __open 1 _open 1 strstr 1 load_zoneinfo 1 ... _ti_bind_guard 47 _ti_bind_clear 94 |