Solaris 动态跟踪指南

宏参数

D 编译器还提供了一组与任何附加参数操作数(指定为 dtrace 命令调用的一部分)对应的宏变量。可使用内置名称 $0 表示 D 程序文件的名称或 dtrace 命令、$1 表示第一个附加操作数、$2 表示第二个操作数,依此类推,来访问这些宏参数。如果使用了 dtrace -s 选项,则 $0 将扩展为与此选项配合使用的输入文件的名称的值。对于在命令行上指定的 D 程序,$0 扩展为用于执行 dtrace 本身的 argv[0] 的值。

宏参数可以扩展为整数、标识符或字符串,具体取决于相应文本的格式。与所有宏变量一样,D 程序中可使用整数、标识符和字符串标记的任何位置均可使用宏参数。以下所有示例都可以构成带有相应宏参数值的有效 D 表达式:

execname == $1    /* with a string macro argument */
x += $1           /* with an integer macro argument */
trace(x->$1)      /* with an identifier macro argument */

宏参数可用于创建 dtrace 解释程序文件,这些文件的作用就像实际的 Solaris 命令,并且使用用户或其他工具指定的信息来修改其行为。例如,以下 D 解释程序文件跟踪按特定进程 ID 执行的 write(2) 系统调用:

#!/usr/sbin/dtrace -s

syscall::write:entry
/pid == $1/
{
}

如果将此解释程序文件设置为可执行文件,则可以使用解释程序文件的附加命令行参数来指定 $1 的值:


# chmod a+rx ./tracewrite
# ./tracewrite 12345

产生的命令调用统计由进程 ID 12345 执行的每个 write(2) 系统调用。

如果 D 程序引用的宏参数不是在命令行上提供的,则会列显相应的错误消息,且程序将编译失败:


# ./tracewrite
dtrace: failed to compile script ./tracewrite: line 4:
  macro argument $1 is not defined

如果设置了 defaultargs 选项,则 D 程序可以引用未指定的宏参数。如果设置 defaultargs,则未指定的参数的值将为 0。有关 D 编译器选项的更多信息,请参见第 16 章。如果在命令行上指定了 D 程序未引用的附加参数,则 D 编译器也将生成错误消息。

宏参数值必须与整数、标识符或字符串的格式匹配。如果参数与这些格式中的任何一种都不匹配,则 D 编译器将报告相应的错误消息。将字符串宏参数指定到 DTrace 解释程序文件时,使用一对额外的单引号将该参数引起来可避免 shell 解释双引号和字符串内容:


# ./foo '"a string argument"'

如果要将 D 宏参数解释为字符串标记(即使这些参数与整数或标识符的格式匹配),请使用两个前导美元符号(如 $$1)作为宏变量或参数名称的前缀,以强制 D 编译器解释参数值(就像参数值是由双引号引起来的字符串一样)。无论是使用 $arg 还是 $$arg 格式的宏来引用 D 字符串转义序列,任何字符串宏参数中的所有常用 D 字符串转义序列(请参见表 2–5)都将被扩展。如果已设置 defaultargs 选项,则使用 $$arg 格式引用的未指定参数的值为空字符串 ("")。