Solaris 动态跟踪指南

向应用程序中添加探测器

库和可执行文件的 DTrace 探测器在相应应用程序的二进制文件的 ELF 部分中定义。本节介绍如何定义探测器,如何将探测器添加到应用程序源代码中,以及如何扩充应用程序的生成过程以包含 DTrace 探测器的定义。

定义提供器和探测器

.d 源文件中定义 DTrace 探测器,该源文件将在编译和链接应用程序时使用。首先,选择用户应用程序提供器的正确名称。对于正在执行应用程序代码的每个进程,会在进程标识符前附加所选择的提供器名称。例如,如果为以进程 ID 1203 执行的 Web 服务器选择提供器名称 myserv,则与此进程对应的 DTrace 提供器名称应为 myserv1203。在 .d 源文件中,添加与以下示例类似的提供器定义:

provider myserv {
	...
};			

接下来,为每个探测器和相应参数添加定义。以下示例定义选择探测器位置中讨论的两个探测器。第一个探测器有两个参数,都为 string 类型,第二个探测器没有参数。D 编译器会将任何探测器名称中的两个连续下划线 (__) 都转换为一个连字符 (-)。

provider myserv {
	probe query__receive(string, string);
	probe query__respond();
};

应该向提供器定义中添加稳定性属性,以便探测器的使用者了解在应用程序的将来版本中发生变化的可能性。有关 DTrace 稳定性属性的更多信息,请参见第 39 章。稳定性属性的定义如下例所示:


示例 34–1 myserv.d:静态定义的应用程序探测器

#pragma D attributes Evolving/Evolving/Common provider myserv provider
#pragma D attributes Private/Private/Unknown provider myserv module
#pragma D attributes Private/Private/Unknown provider myserv function
#pragma D attributes Evolving/Evolving/Common provider myserv name
#pragma D attributes Evolving/Evolving/Common provider myserv args

provider myserv {
	probe query__receive(string, string);
	probe query__respond();
};


注 –

使用用户添加的探测器中的非整型参数的 D 脚本必须使用 copyin()copyinstr() 函数来检索这些参数。有关更多信息,请参见第 33 章


向应用程序代码中添加探测器

至此,已在 .d 文件中定义了探测器,接下来需要扩充源代码以指示应触发探测器的位置。以下面的 C 应用程序源代码为例:

void
main_look(void)
{
	...
	query = wait_for_new_query();
	process_query(query)
	...
}

要添加探测器位置,请添加对 <sys/sdt.h> 中定义的 DTRACE_PROBE() 宏的引用,如下例所示:

#include <sys/sdt.h>
...

void
main_look(void)
{
	...
	query = wait_for_new_query();
	DTRACE_PROBE2(myserv, query__receive, query->clientname, query->msg);
	process_query(query)
	...
}

宏名称 DTRACE_PROBE2 中的后缀 2 表示将传递到探测器的参数个数。探测器宏的前两个参数是提供器名称和探测器名称,它们必须与 D 提供器和探测器定义对应。其余的宏参数是在触发探测器时将赋给 DTrace arg0..9 变量的参数。应用程序源代码可以包含对同一个提供器和探测器名称的多次引用。如果源代码中存在对同一个探测器的多次引用,则任何宏引用都将导致触发探测器。

生成包含探测器的应用程序

您必须扩充应用程序的生成过程以包含 DTrace 提供器和探测器定义。通常的生成过程会获取每个源文件,然后编译这些文件以创建相应的对象文件。然后再将编译后的对象文件链接在一起以创建最终的应用程序二进制文件,如下例所示:


cc -c src1.c
cc -c src2.c
...
cc -o myserv src1.o src2.o ...

要在应用程序中包含 DTrace 探测器定义,请向执行 dtrace 命令的生成过程中添加相应的 make 程序的描述文件规则,如下例所示:


cc -c src1.c
cc -c src2.c
...
dtrace -G -32 -s myserv.d src1.o src2.o ...
cc -o myserv myserv.o src1.o src2.o ...

如上所示的 dtrace 命令将对前面的编译器命令生成的对象文件进行后期处理,并生成对象文件 myserv.o(通过 myserv.d)和其他对象文件。dtrace -G 选项用于将提供器和探测器定义与用户应用程序链接起来。-32 选项用于生成 32 位应用程序二进制文件。-64 选项用于生成 64 位应用程序二进制文件。