分享
 
 
 

C/C++内存问题检查利器—Purify (五)

王朝c/c++·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

十、 设置WatchPoint

你可以在你的程序中,对你所想监控的程序设置一些WatchPoint,以方便于你对程序进行调试,或更容易找出问题的原因。就像我前面说,Purify可以找到你的内存泄露,但其不能找到内存泄露的原因,你可以通过设置WatchPoint来跟踪一块内存,以找到在程序执行过程中该内存的访问情况。

Purify的WatchPoint可以产生下例消息:

l WPR(被WatchPoint的内存读)

l WPW(被WatchPoint的内存写)

l WPM(被WatchPoint的内存分配)

l WPF(被WatchPoint的内存释放)

l WPN(来到被WatchPoint的内存的Scope)

l WPX(离开被WatchPoint的内存的Scope)

一旦你设置好了一个WatchPoint,Purify会自动报告上述这些信息,以告诉你内存的存取情况。很方便你调试程序。

WatchPoint一般是在调试程序时跟踪一块内存时候使用的,你也可以用其跟踪一些系统级的全局变量,如:errno。一旦errno被写了,马上会报告一个WPW消息,展开后,你能看到函数的堆栈情况,以及是在哪个系统调用后出现了错误。这个使用很方便我们找到一些非内存方面的问题。

大家可能会有一种感觉,那就是在一般的调试器中,如GDB中也有WatchPoint的设置(对GDB的使用请参考我的文章《用GDB调试程序》),那么,在调试器中的WatchPoint和Purify的有什么不同?下面是一些GDB中的WatchPoint不足的地方:

1) GDB中的WatchPoint用于单步跟踪中。

2) GDB中的WatchPoint只能在其内存的Scope中,离开了Scope,WatchPoint会被删除。

3) 在GDB中设置一个4字节的内存WatchPoint,会让程序的运行效率下降1000个数量级。

Purify中的WatchPoint有效地克服了这些问题,它在全局范围内监控所有内存的使用,并且,其速度上大大地快于GDB等一系列的调试器。

有两种方式可以让我们设置Purify的WatchPoint,一种是在程序中使用WatchPoint的API函数,一种是直接在调试器中使用(如:GDB),下面我介绍一下这两种用法:

1、 在程序中使用。

写下这段程序:

#include <errno.h>

main()

{

int i;

printf("Note: errno=0x%x\n", errno);

purify_watch(&errno);

errno = 0;

close(1000);

exit(0);

}

用Purify编译: >sudo purify gcc -g -o watch watch.c

运行后,我们可以看到以下画面:

我们可以看到,Purify成功地监控了errno变量。我们还可以看到被监控的变量改变前和改变后的值。

2、 在GDB中使用。

在GDB中,我们可以简单地使用GDB的print命令来达到设置Purify的WatchPoint目的。这正是Purify的强大之处,其对这种技术称为JIT(Just-In-Time)。

示例:

gdb) print purify_watch(&my_str)

(gdb) print purify_watch_1(&my_char)

(gdb) print purify_watch_n(buf, sizeof(buf), "rw")

(dbx) print purify_watch_n(write_only_buf,100,"w")

下面来让我们看一看Purify的WatchPoint的API函数,其分成三类:

• 设置类

int purify_watch(char *addr)

对所指定的内存进行监视,char* 表示以单字节为单位。

int purify_watch_<num> (char *addr) <num>=1,2,4,8

其中的<num>是一个数字,可以是1,2,4,8表示,监控单字节,双字节,四字节,八字节。函数名为:purify_watch_1(),purify_watch_2(),purify_watch_4(),purify_watch_8。

int purify_watch_n(char *addr, unsigned int size, char *type)

(type = “r”, “w” or “rw”)

监控特定长度的内存,type取值为“r”,“w”“rw”,意为监控内存的读还是写。

• 查询类

int purify_watch_info().

打印目前设置的WatchPoint的情况(一般在GDB类的调试器中使用)。有点像GDB的info watch命令。

• 删除类

Int purify_watch_remove(int watchno)

删除指定的WatchPoint,其watchno为设置WatchPoint的函数的返回值。

int purify_watch_remove_all()

删除所有的WatchPoint。

十一、 使用Purify的参数

Purify的参数很多,具体的参数我就不多说了,还请你参考其使用手册。在这里,我简单地讲一讲其参数的使用规则和方式。

Purify的参数使用的规则如下:

1、 必须以连字符开始,也就是减号。

2、 在等号(=)的两端不能有空格。

3、 忽略参数名和变量的大小写。

4、 其参数中的连接符可以是减号,下划线,或是干脆就没有。如:

-leaks-at-exit,-LEAKS_AT_EXIT和 –LeaksAtExit是一回事。

5、 在参数中,如果你要指多个路径,可以用冒号或空格分开。使用空格时请使用引号。如:

% purify -user-path=’/usr/home/program /usr/home/program1’

% purify -user-path=/usr/home/program:/usr/home/program1

6、 指写多个邮件用户时,用逗号分隔。千万不要回空格。如:

% purify -mail-to-user=chris,pat,kam

7、 可以使用通配符或转义字串。如:

program* 和 -log-file=./%v.plog

Purify参数的类型有三种——布尔、字符串和整数,如:

-leaks-at-exit=yes 布尔型

-log-file=./pureout 字符串型

-chain-length=10 整数型

设置参数的方法有三种:

1、 在图形窗口中,通过点击“Options -> Runtime”菜单,在对话框中设置。

2、 通过两个环境变量设置——PURIFYOPTIONS 或 PUREOPTIONS,如:

在csh下:

% setenv PURIFYOPTIONS "-log-file=new $PURIFYOPTIONS“

在sh或ksh下:

$ PURIFYOPTIONS="-log-file=new $PURIFYOPTIONS"; export PURIFYOPTIONS

3、 在Link程序的命令行中。如:

$ purify -cache-dir=$HOME/pcache -always-use-cache-dir $CC ...

十二、 使用Purify的API函数

Purify的函数有许多,我也不在这里一一讲解了,其具体细节还请参考使用手册。我这里只讲一下Purify的API函数的使用方法。总的说来,有以下两种方式我们可以使用Purify的API函数。

1. 在我们的调试器中调用,如:

gdb) print purify_describe(addr)

(dbx) call purify_what_colors(buf, sizeof(buf))

(xdb) p purify_describe(addr)

注:对于purify_stop_here这个函数,我们可以这样使用。

(gdb) break purify_stop_here

(dbx) stop in purify_stop_here

(xdb) b purify_stop_here

2. 在自己的程序中调用。要在程序中调用Purify的API函数,我们需要下面两步:

1)加上头文件:#include <purify.h>

2)把LIB文件放到可被搜索到的路径中。主要是一个动态链接库文件libpurify_stubs.so和一个静态链接库文件libpurify_stubs.a

十三、 结束语

Purify是一个很强大的工具,但可惜的是其只能是某几个平台中使用。好像其Windows版中的功能要差很多,我用的Sun的Solaris的版本,很不错,因为我们的程序要在所有的UNIX下跑,用C跨平台,所以,使用Solaris来做测试机。对于其它平台的Purify,我没有用过,不知道和Solaris下的是否一样,还希望有经验的同行给我指点。不管怎么样,我想信IBM的Rational部会把它做得越来越好的。

对于这篇文章,本来打算在9月或者10月写这篇文章的。不过实在没有办法,前些时候太忙了,忙得脑子一堆浆糊,只要拖到现在,现在较好一点,不过脑子也不好用,写作过程中发现脑袋很拙笨。所以写出来的东西一点有错误,特别是我用的是五笔输入法,所以有错字错词会有可能让你看不懂,还请各位见谅。

好了,不多说了,好累了。还是留上我的联系方式,欢迎和我讨论交流。本人目前主要在UNIX下做产品软件设计和管理工作,所以,对UNIX下的软件开发比较熟悉,当然,不单单是技术,对软件工程实施,软件设计,系统分析,项目管理我也略有心得。欢迎大家找我交流。(MSN是:haoel@hotmail.com(常用) QQ是:753640(基本不用,因为不安全))

<-上一页

(全文完)

(版权所有,转载时请注明作者和出处)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有