七、 Purify的退出码
像
UNIX
下的软件,一般都会提供和别的应用程序的接口,像上面的生成文本文件,也是给别的应用程序提供接口的一种方式。这里,我们所要讲述的是
Purify
的退出码,我们知道程序都有退出码,以提供给别的程序或操作系统自己运行的信息。被
Purify
编译过的程序,你可以通过指定
-exit-status
参数来告诉
Purify
是否用
Purify
的退出码,如果这个参数值为
yes
,那么表示使用
Purify
的退出码,如果值为
no
则表示使用程序内的退出码。
如果我们这样设置:
-exit-status=yes
,那么
Purify
的退出码是这样定义的:
内存错误种类
|
退出码(按位或)
|
内存存取错误
|
0x40
|
内存泄露
|
0x20
|
潜在内存泄露
|
0x10
|
通过上表,我们可以知道,当
-exit-status
参数被打开后,程序的退出码被
Purify
完全接管,如果程序中有内存错误,那么退出码所对应的位就会被置为
1
,这样,我们可以用别的程序来调用
Purify
所编译出来的程序,并根据其退出码作相应的处理。
八、 Purify和Shell的集成
你可以在
UNIX
的
Shell
环境中使用
Purify
的一些参数和信息,
Purify
为
Shell
提供了一些通配符之类的东西,只要你使用
�Crun-at-exit
参数。例如你有一个
Shell
程序想把
Purify
生的文件拷贝到别的目录中,或是你想根据
Purify
的报告中是否有内存错误进行下一步的行动。
下面有两个表格,说明了一些
Purify
和
Shell
交互的参数:
有关内存出错的信息:
通配字符串
|
含义
|
%z
|
指明是否有内存错误或内存泄露。其值是“
true
”或“
false
”
|
%x
|
程序的退出状态(如果是
0
,表示程序没有调用
exit
函数)
|
%e
|
程序中内存访问错误的个数。
|
%E
|
程序中错误总数。
|
%l
|
内存泄露的字节数。
|
%L
|
潜在内存泄露的字节数。
|
有关程序运行的信息:
通配字符串
|
含义
|
%V
|
运行程序的全路径(“
/
”被替换成了“
_
”)
|
%v
|
程序的名称
|
%p
|
程序的进行
ID
|
在使用
Purify
过程中,有两种方法可以传递
Purify
的参数,一种就是在命令行上指明。另外一种是设置一个和
Purify
相关的环境变量:
PURIFYOPTIONS
。现在,我通过这个环境变量要举一个例子,以说明上面表格中的参数在使用中的情况:
例如,如果我们这样这置环境变量:(在
C-Shell
中)
setenv PURIFYOPTIONS '-run-at-exit="if %z ; then \
echo \"%v: %e errors, %l+%L bytes leaked.\" ; fi"'
当我们运行被
Purify
编译过的程序后,会出现以下结果:
hello: 2 errors, 1+10 bytes leaked.
我们可以看到,由于
hello
程序出错了,所以
%z
为“
true
”,所以
Purify
执行
echo
命令,其中,
%v
表示了程序名(
hello
),
%e
表示了错误的个数(
2
),
%l
表示了内存泄露的字节数(
1
),
%L
表示了程序中有潜在可能的内存泄露字节数(
12
)。
让我们再来看两个例子:
示例一:
指定
Purify
的参数为:
-log-file=./%v.plog
示例二:
指定
Purify
的参数为:
-view-file=/home/hchen/%V.pv
总这,这些有“
%
”的变量,都是
Purify
提供给操作系统
Shell
的,以供
Shell
编程使用的。
九、 过滤Purify的报告信息
如果你的程序比较大,模块也比较多,有时候出现的信息非常的多,你程序中很可能有某段代码产生了若干个内存错误,所以,我们可以使用
Purify
的过滤器来让
Purify
只显示某一种类的信息,这样方便我们进行问题的查找和排错。
1、
在
Purify
的
X-Window
中设置信息过滤,点击图形界面中的菜单“
Options
”
-�C>
“
Suppressions
”,将出现“
Suppressions
”对话框,如下所示:
我们可以看到在上面的对话框中,如果过滤
Purify
的报告信息。当我们点击“
Where to suppress
”只要,我们会看到有如下的五个选项:
l
In Call Chain
:表示在某个函数调用链中信息。
l
In File
:表示只报告在某个文件中的信息。
l
In Library
:表示只报告在某个
LIB
文件中的信息。
l
In Class
:这是
C++
的,表示报告某个类的信息。
l
Everywhere
:表示全部范围内的信息。
但是图形界面中,
Purify
并没有给我们提供一个选取文件或
LIB
或类的对话框,我们只能通过其文本语法来描述,接下来就让我们来看一看,过滤
Purify
报告信息的文本语法。
2、
我们可以使用
Purify
的过滤语法来要求
Purify
的过滤信息。并把其存于
.purify
文件中,这样当我们的
Purify
起动后载入这个文件,就可以达到过滤信息的目的了。通过文本语法来设置过滤信息比图形界有更为强大的地方。下面还是来看看
suppress
的语法:
语法:
suppress <message-type> <function-call-chain>
unsuppress <message-type> <function-call-chain>
其中,
suppress
和
unsuppress
中关键字,分别表示过滤或不过滤。
<message-type>
指明要操作的消息,可以使用“
*
”做通配符,
<function-call-chain>
表示函数的调用链,调用的函数链用分号分隔,其同样可以使用“
*
”做通配符,还可以使用“
…
”来表示无论中间是什么。
还是来看几个示例吧:
1)
suppress AB*
表示过滤
ABR
和
ABW
错误。
2)
suppress *W
表示过滤
ABW
、
FMW
、
IPW
、
NPW
、
SBW
、
WPW
和
ZPW
错误。
3)
suppress ABR “libc*”
表示在所有以
libc
打头的
LIB
文件中过滤
ABR
信息。
4)
suppress ABR sortFunction; sort*; qsort; “libc*”
其表示,过滤
ABR
错误。过滤范围是在
sortFunction
中,并且是在以
libc
开头的函数库文件中,其调用链是
qsort -> sort* -> sortFunction
。换言之,只要有“
libc*
”文件中的函数调用了
qsort
,并且
qsort
调用了开头为
sort*
的函数,并且这些函数调用了
sortFunction
,那么,在这一个函数链中,不显示
ABR
错误信息。
5)
suppress UMR tzsetWall;…; main
其表示,在
tzsetWall
函数中过滤
URM
信息,只要
tzsetWall
函数是被
main
函数间接调用的,无论有多远,都不显示
UMR
信息。
6)
suppress FNH Test: :Test
这是
C++
中使用的语法,表示在类
Test
所有的构造函数中过滤
FNH
信息。如果要指明特定的函数,请加上其参数类型,如:
suppress FNH Test::Test(const char*)
。
注意,“
…
”语法表示调用链无论有多远。当然,如果你设置了参数“
-chain-length=6
”,那么,“
…
”只能到
6
层函数调用,
7
层的就不管了。
在启动
Purify
时,我们可以这样来读取
.purify
文件:
% purify -suppression-file-names=".purify,.purify.sunos4,\
$HOME/purify_suppressions"
Purify
会在下面的目录中寻找这个文件:
<purifyhome>/.purify
<purifyhome>/.purify.sunos4
$HOME/.purify
$HOME/.purify.sunos4
<progdir>/.purify
<progdir>/.purify.sunos4
$HOME/purify_suppressions