受支持的 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 捕获的数据进行内部排序。