实际上,pid 定义了一个提供器类。每个进程都可能具有独立关联的 pid 提供器。例如,ID 为 123 的进程将使用 pid123 提供器进行跟踪。对于来自这些提供器的其中之一的探测器,探测器说明的模块部分将引用对应进程的地址空间中装入的对象。以下示例使用 mdb(1) 显示对象列表:
$ mdb -p 1234 Loading modules: [ ld.so.1 libc.so.1 ] > ::objects BASE LIMIT SIZE NAME 10000 34000 24000 /usr/bin/csh ff3c0000 ff3e8000 28000 /lib/ld.so.1 ff350000 ff37a000 2a000 /lib/libcurses.so.1 ff200000 ff2be000 be000 /lib/libc.so.1 ff3a0000 ff3a2000 2000 /lib/libdl.so.1 ff320000 ff324000 4000 /platform/sun4u/lib/libc_psr.so.1 |
在探测器说明中,将根据文件名而不是其完整路径名来命名对象。此外,也可以省略 .1 或 so.1 后缀。以下所有示例命名的探测器都相同:
pid123:libc.so.1:strcpy:entry pid123:libc.so:strcpy:entry pid123:libc:strcpy:entry
第一个示例是探测器的实际名称。其他示例则是为方便而使用的别名,在内部,该别名将被替换为完整的装入对象名称。
对于可执行文件的装入对象,可以使用别名 a.out。以下两种探测器描述指定了同一探测器:
pid123:csh:main:return pid123:a.out:main:return
与所有固定 DTrace 探测器一样,探测器描述的函数字段指定模块字段中的函数。用户应用程序二进制文件的同一个函数可能有多个名称。例如,mutex_lock 可能为 libc.so.1 中函数 pthread_mutex_lock 的备选名称。DTrace 为这样的函数选择一个标准名称,并在内部使用该名称。以下示例说明了 DTrace 在内部如何将模块和函数名称重新映射为标准形式:
# dtrace -q -n pid101267:libc:mutex_lock:entry'{ \ printf("%s:%s:%s:%s\n", probeprov, probemod, probefunc, probename); }' pid101267:libc.so.1:pthread_mutex_lock:entry ^C |
这种自动重命名意味着,您启用的探测器名称可能与实际启用的探测器名称略有不同。在运行同一个 Solaris 发行版的系统上,每次运行 Dtrace 时,标准名称总是保持一致。
有关如何有效使用 pid 提供器的示例,请参见第 33 章。