受支持的 shell 元素
Vue 语言语法支持由 $ 前缀标识的 shell 变量,例如导出的 shell 变量和位置参数 (脚本的自变量)。
Vue shell 变量可以出现在 Vue 脚本中的任何位置。 它们可以是调查规范的一部分,可以用于谓词中或操作块的语句中。 但是,与 shell 脚本不同,如果用于由双引号引起的字符串中,那么不能对它们进行扩展。
从命令行传送给脚本的变量以 $1、$2、$3 等形式在脚本中引用。 请考虑以下 Vue 脚本:
/* Program name: myscript.e */
@@syscall:*:read:entry
when (__pid == $1)
{
int count;
count++;
}
在以下示例中,运行 myprog 程序的进程的进程标识将替换上述脚本中的 $1。 它假定 prgrep shell 程序 (打印给定进程名称的进程标识) 用于调用 Vue 脚本。
probevue myscript.e `prgrep myprog`
从 shell 导出的环境变量也可以在使用 $ 运算符的脚本中进行引用。 请考虑以下 Vue 脚本:
/* Program name: myscript2.e */
@@syscall:*:read:entry
when (__pid == $PID)
{
int count;
count++;
}
/* program to be traced has a function called 'foo' */
@@uft:$PID:*:foo:entry
{
printf("Read system call was invoked %d times\n", count);
}
在以下示例中,3243 替换前述脚本中的 $PID。
PID=3423 probevue myscript2.e
如果需要将环境变量识别为 ProbeVue 脚本中的字符串,那么该环境变量的值必须包含将其标识为字符串的双引号。 例如,在系统中打开特定文件时,以下脚本会捕获跟踪输出:
/* Program name: stringshell.e */
int open(char *path, int oflag);
@@syscall:*:open:entry
{
String s[40];
s = get_userstring(__arg1, -1);
if (s == $FILE_NAME) {
printf("pid %d (uid %d) opened %s\n",__pid,__uid, s);
exit();
}
}
脚本期望 $FILE_NAME 是已导出 shell 环境变量的名称,该变量值由双引号引起。 请参见以下脚本示例:
export FILE_NAME=\"/etc/passwd\"
probevue stringshell.e
如果脚本中需要不带双引号的现有环境变量的值,那么将需要使用双引号将现有环境变量引起来以构建新的环境变量。 请参见以下脚本示例:
export FILE_NAME=\"$HOME\"
probevue stringshell.e
如果要调查的进程由 probevue 命令本身使用 -X 标志启动,那么 Vue 支持在这种情况下会很有用的两个特殊的环境变量。 $__CPID 环境变量表示由 probevue 命令创建的子进程的进程标识,而 $__CTID 环境变量表示其线程标识。 调查生命期比较短的进程,特别是为调试目的而进行调查时,-X 标志非常有用。
可以通过将第一行设置为以下脚本来直接执行 Vue 脚本 (如 shell 脚本):
#!/usr/bin/probevue
probevue 命令还可以像 shell 一样从标准输入读取 Vue 脚本。 可以通过从命令行省略脚本文件名来实现此操作。 这对于测试简短脚本比较有用。
Vue 不支持由 shell 在内部创建的特殊 shell 参数,例如 $$ 和 $@ 。
跟踪捕获工具
ProbeVue 支持全面的跟踪捕获工具。 基本的跟踪捕获操作通过 printf 函数提供,该函数可作为操作块的一部分从任何调查调用。 Vue 版本的 printf 函数配备了 C 库版本的大部分功能。 另一个跟踪捕获函数是 trace 函数。 trace 函数将单个变量作为参数接受,并将其值以可显示的十六进制格式复制到跟踪缓冲区。 此函数对于转储字符串和结构的内容特别有用。 stktrace 函数是另一个跟踪捕获函数,它捕获当前探针点处所跟踪线程的堆栈跟踪。
除了内部脚本变量的值以外,外部变量(如内核全局变量)、特定于上下文的数据(如正被探测的函数的参数)以及函数的返回值等也可通过这些跟踪捕获函数进行捕获和显示。
跟踪报告程序总是以发生的时间顺序显示跟踪数据,因此在输出这些数据之前,会对从不同 CPU 捕获的数据进行内部排序。