Solaris 动态跟踪指南

入门

使用 DTrace,可以动态修改操作系统内核和用户进程,以记录您在所关注的位置(称为探测器)指定的其他数据,从而帮助您了解软件系统。探测器是一个位置或活动,DTrace 可以将请求绑定到该位置或活动中,以便执行一组操作,如记录栈跟踪、时间标记或函数参数。探测器类似于分散在整个 Solaris 系统中受关注位置的可编程传感器。如果要确定系统的状态,可使用 DTrace 对相应的传感器进行编程,以便记录您关注的信息。然后,当每个探测器触发时,DTrace 便会从探测器中收集数据并向您报告。如果未为探测器指定任何操作,DTrace 将仅记录探测器的每次触发。

在 DTrace 中,每个探测器都有两个名称:一个唯一的整数 ID 以及一个人工可读的字符串名称。接下来,我们将通过使用名为 BEGIN 的探测器生成一些非常简单的请求来开始学习 DTrace,该探测器在每次启动新的跟踪请求时触发一次。您可以使用 dtrace(1M) 实用程序的 -n 选项,通过探测器的字符串名称来启用探测器。键入以下命令:


# dtrace -n BEGIN

在简短暂停后,DTrace 将会通知您已启用一个探测器,并且会显示一行输出,表明 BEGIN 探测器已被触发。显示此输出后,dtrace 将保持暂停状态,以等待其他探测器触发。由于尚未启用任何其他探测器,并且 BEGIN 仅触发一次,因此可在 shell 中按 Ctrl-C 组合键,退出 dtrace 并返回到 shell 提示符:


# dtrace -n BEGIN
dtrace: description 'BEGIN' matched 1 probe
CPU     ID		      FUNCTION:NAME
  0      1                  :BEGIN
^C
#

该输出表明,名为 BEGIN 的探测器已被触发一次,并且还会列显其名称和整数 ID 1。请注意,缺省情况下会显示触发此探测器的 CPU 的整数名称。在此示例中,CPU 列表明触发该探测器时,正在 CPU 0 上执行 dtrace 命令。

您可以使用任意数量的探测器和操作构造 DTrace 请求。通过在上一示例命令中添加 END 探测器,我们来使用两个探测器创建一个简单的请求。END 探测器在完成跟踪时触发一次。请键入以下命令,然后在显示 BEGIN 探测器的输出行后,再次在 shell 中按 Ctrl-C 组合键:


# dtrace -n BEGIN -n END
dtrace: description 'BEGIN' matched 1 probe
dtrace: description 'END' matched 1 probe
CPU     ID		      FUNCTION:NAME
  0      1                  :BEGIN
^C
  0      2                    :END
#

如您所见,按 Ctrl-C 组合键退出 dtrace 时可触发 END 探测器。dtrace 在退出之前,会报告 此探测器的触发情况。

至此,您已大致了解了如何命名和启用探测器,现在便可以尝试编写最简单的 DTrace 版程序 "Hello, World"。除了可在命令行中构造 DTrace 实验脚本之外,还可使用 D 编程语言在文本文件中进行编写。在文本编辑器中,创建一个称作 hello.d 的新文件,然后键入您的第一个 D 程序:


示例 1–1 hello.d:采用 D 编程语言编写的 "Hello, World"

BEGIN
{
	trace("hello, world");
	exit(0);
}

保存程序后,可以使用 dtrace -s 选项运行该程序。键入以下命令:


# dtrace -s hello.d
dtrace: script 'hello.d' matched 1 probe
CPU     ID		      FUNCTION:NAME
  0	    1                  :BEGIN   hello, world
#

如您所见,dtrace 显示的输出与前面相同,后跟文本 "hello, world"。与上例不同的是,您不需要等待,也不需要按 Ctrl-C 组合键。这些更改是在 hello.d 中为 BEGIN 探测器指定的操作的结果。为了解所发生的情况,让我们来看看 D 程序的详细结构。

每个 D 程序均由一系列子句组成,每个子句用于描述一个或多个要启用的探测器,以及触发探测器时要执行的一组可选操作。这些操作以一系列括在大括号 { }(跟在探测器名称后面)中的语句形式列出。每条语句都以分号 (;) 结尾。您的第一条语句使用函数 trace() 来指示 DTrace 应在触发 BEGIN 探测器时记录指定的参数(字符串 "hello, world"),然后将其显示出来。第二条语句使用函数 exit() 来指示 DTrace 应停止跟踪并退出 dtrace 命令。DTrace 提供了一组类似于 trace()exit() 的有用函数,供您在 D 程序中调用。要调用函数,请指定函数名称,并后跟用括号括起的参数列表。有关全套 D 函数的描述,请参阅第 10 章

如果您熟悉 C 编程语言,则此时您可能已从名称和示例了解到,DTrace 的 D 编程语言与 C 编程语言非常类似。实际上,D 源自一个大型的 C 子集和一组可简化跟踪的特定函数和变量。在后续章节中,您将会进一步了解这些功能。如果您以前编写过 C 程序,则可将大部分知识立即运用到 D 中生成跟踪程序。如果您以前从未编写过 C 程序,学习 D 也很容易。经过本章的学习后,您将了解所有语法。不过,让我们首先从语言规则开始,进一步了解 DTrace 的工作方式,然后再返回来学习如何生成更有趣的 D 程序。