C/C++内存问题检查利器―Purify (四)

七、             Purify的退出码

UNIX 下的软件,一般都会提供和别的应用程序的接口,像上面的生成文本文件,也是给别的应用程序提供接口的一种方式。这里,我们所要讲述的是 Purify 的退出码,我们知道程序都有退出码,以提供给别的程序或操作系统自己运行的信息。被 Purify 编译过的程序,你可以通过指定 -exit-status 参数来告诉 Purify 是否用 Purify 的退出码,如果这个参数值为 yes ,那么表示使用 Purify 的退出码,如果值为 no 则表示使用程序内的退出码。
 
如果我们这样设置: -exit-status=yes ,那么 Purify 的退出码是这样定义的:
 
内存错误种类
退出码(按位或)
内存存取错误
0x40
内存泄露
0x20
潜在内存泄露
0x10
 
通过上表,我们可以知道,当 -exit-status 参数被打开后,程序的退出码被 Purify 完全接管,如果程序中有内存错误,那么退出码所对应的位就会被置为 1 ,这样,我们可以用别的程序来调用 Purify 所编译出来的程序,并根据其退出码作相应的处理。
 
 

八、             PurifyShell的集成

你可以在 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

你可能感兴趣的:(C++,内存,purify)