即使对于老练的程序员和系统管理员,应用程序开发和故障排除也是艰难的任务。即使有了最好的调试器,程序员有时候仍然希望用简单的打印语句检查应用程序正在执行的操作。IBM® AIX® V6 增加了一种新的调试工具,ProbeVue。本文简要介绍 ProbeVue 的用法以及相关联的编程和脚本语言,并通过一个简单的示例程序演示 ProbeVue 的用途和潜在价值。

Brad Cobb, AIX Collaboration Center 高级技术顾问, IBM

Brad 十多年来一直帮助解决方案提供者在 IBM AIX 环境中移植、优化、测试和增强他们的应用程序。除了帮助解决方案提供者以外,Brad 还喜欢申请各种专利、发表文章以及在开发人员会议上进行演讲。



2008 年 11 月 06 日

简介

ProbeVue 这种跟踪工具使用户可以动态地跟踪正在运行的程序。ProbeVue 的主要接口是 VUE 语言。VUE 既是编程语言,也是脚本语言。VUE 语言与 C 语言和 AIX 可用的脚本语言相似。

VUE 语法

ProbeVue 脚本的基本形式与结构良好的 C 程序和 awk 脚本相似。VUE 脚本文件的一般形式如下:

Variable definitions

Begin {
}

Probe clauses

End {
}

变量部分

在变量部分中定义全局变量。与 C 语言一样,可以在文件中的其它地方指定临时变量。VUE 支持以下变量类型:

  • C-89 数据类型(包括有符号和无符号)short、int、long、long long、float 和 double。对于浮点变量的操作只限于简单的赋值表达式和作为 VUE 函数的变量。
  • String 数据类型代表字符串字面值。例如,String fooString[20] 声明一个长度为 20 的字符串字面值。只需用 fooString = “My String” 初始化 fooString。可以使用 + 操作符连接多个字符串字面值。
  • List 数据类型表示一组整数类型的值。例如,fooList = list() 创建 List fooList。使用 append 函数在 fooList 中添加值:append( fooList, value ),其中的 value 可以是另一个列表或整数变量。除了 append 函数之外,List 数据类型还支持 avg() 函数(计算列表的平均值)、min() 函数(判断列表中的最小值)、max() 函数(判断列表中的最大值)和 count() 函数(返回列表的大小,即列表中的条目数量)。
  • probev_timestamp_t 是一种特殊的数据类型,用来从 VUE 时间戳函数返回值。返回的值采用 AIX 内部格式。

环境变量

在环境变量名称前面加上 $(美元)符号,就可以在 VUE 脚本中使用环境变量。在默认情况下,环境变量存储整数值。要想保证传递字符串,环境变量必须用双引号定义变量:export MYENV=\”123\” 传递字符串 123,而 export MYENV=123 传递整数值一百二十三

除了传递环境变量之外,VUE 还支持几个内置的环境变量:

  • __CPID 是 ProbeVue 命令创建的子进程的进程 ID。
  • __CPTID 是线程 ID。

Begin 部分

begin 部分是 VUE 脚本中用来执行变量初始化的部分。在脚本开始执行时调用这个部分,而且只执行一次。


探测子句(Probe clauses)

探测子句部分包含程序逻辑。程序员在这个部分中定义各个探测点。下一节详细讨论各种探测类型,这些探测类型包括系统调用、用户函数和内部。

探测类型

Probevue 提供以下探测类型:


系统调用探测

系统调用探测(即 syscall 探测)用来探测 libc 库和内核中的函数。可以为函数调用的进入或退出定义探测。系统调用探测的一般形式如下:

@@syscall:<process_ID>:<system_call_name>:<entry|exit>

其中:

  • <process_ID> 是要探测的进程(例如,123675 或表示所有进程的 *)
  • <system_call_name> 是要探测的系统调用(例如,read)
  • <entry> 对函数调用的进入执行探测
  • <exit> 对函数调用的退出执行探测

通过使用系统调用探测,可以在 VUE 脚本中使用输入参数和返回值。为了访问输入参数,VUE 脚本必须声明要探测的函数的函数原型。例如:

int read( int fd, char *buf, unsigned long size );

指定这一行,VUE 脚本就能够访问 fd、buf 和 size 参数。使用一个特殊的内置变量 __arg3 捕捉函数的返回值。


用户函数探测

用户函数探测应用于应用程序代码级探测。用户函数探测的一般形式如下:

      @@uft:<processID>:*:<function_name>:entry

其中:

  • process_ID 是要探测的可执行程序的进程 ID
  • function_name 是要探测其进入的用户函数

与系统调用探测不同,用户函数探测必须指定一个进程 ID,而且只能探测函数的进入。


内部探测

内部探测是以一定的时间间隔执行的探测。内部探测的一般形式如下:

      @@interval:*:clock:<# milliseconds>

其中 <# milliseconds> 以 100ms 为单位定义时间间隔。

命令语法

ProbeVue 命令行提供各种选项。本文主要关注 ProbeVue 命令的以下形式。后面的 ProbeVue 示例脚本也使用这种形式。

probevue [ -X Program_name [ -A "Arguments_to_program" ] ] 
[ Script_name [ Arguments_to_script ] ]

其中:

-X启动一个程序并在启动程序之前启用探测。
-A为使用 -X 标志指定的程序指定参数。
Script_name包含要运行的 ProbeVue 脚本的文件。

指定 –X 选项,这会在指定的命令执行期间运行 ProbeVue。ProbeVue 的这种用法有助于探测单一程序。


系统调用探测示例

前面已经简要解释了脚本语法和探测类型,现在来看一个使用系统调用探测的简单 ProbeVue 脚本。

清单 1:系统调用 ProbeVue 脚本示例
/* Function prototype for read in order to access input args */
int read( int fd, char *buf, unsigned long size );

String sFormat0[10];
String sFormat1[10];
String sLen[2];

@@BEGIN
{
	/* Initialize printf format strings */
	sLen = "9";
	sFormat0 = "%" + sLen + "d,";
	sFormat1 = "%" + sLen + "d," + "%" + sLen + "d\n";
	sFormat2 = "%" + sLen + "s,%" + sLen + "s,%" + sLen + "s\n";

	/* Print header */
	printf( sFormat2, "Requested", "Actual", "Average" );

	/* Create list to maintain rolling average */
	rollingAvg = list();
}


/* Probe to print the size of the read buffer. */
@@syscall:*:read:entry 
	/* Only for the currently executing program. */
	when ( $__CPID == __pid ) {
		/* __arg3 represents the size of the read buffer. */
		printf( sFormat0, __arg3 );
        }

/* Probe to print the actual number of bytes read i.e. the return value from read. */
@@syscall:*:read:exit 
	/* Only for the currently executing program. */
	when ( $__CPID == __pid ) {
		/* Append return value (__rv) to list */
		append( rollingAvg, __rv );
		printf( sFormat1, __rv, avg( rollingAvg) );
	}

@@END
{
}

显示数据

这个系统调用 ProbeVue 脚本示例的输出采用 Microsoft® Excel® CSV(逗号分隔的值)格式。收集和格式化数据的方式数不胜数,但这个简单的脚本和格式可以获取应用程序的信息,在以前,这需要通过应用程序中的特定代码来实现。通过使用 ProbeVue,在应用程序之外执行这个脚本的代码。下面是这个程序的输出示例:

probevue -X /usr/bin/tar -A "-cf /dev/null /scratch/bcobb/probevue" ./p2.e | tee t.csv
RequestedActualAverage
409617031703
40960851
409640961933
409611601739
40963141454
409618651523
40965751387
40965751286
40963711184

使用这个输出创建一个如下图所示的图表。

清单 1 系统调用 ProbeVue 脚本产生的图表
清单 1 系统调用 ProbeVue 脚本产生的图表

结束语

本文从程序员的角度简要介绍了 AIX 工具集中的 ProbeVue。本文讨论了 ProbeVue 的基本概念,包括 ProbeVue 脚本的一般形式、VUE 编程语言和一个简单但有意义的示例脚本。

参考资料

学习

获得产品和技术

  • 下载 IBM 产品评估版 并开始使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere 的应用程序开发工具和中间件产品。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX
ArticleID=350235
ArticleTitle=ProbeVue 简介
publish-date=11062008