三、 示例
假设我们现在有这样一段程序:hello.c
#include <stdio.h>
#include <malloc.h>
static char *helloWorld = "Hello, World";
main()
{
char *mystr = malloc(strlen(helloWorld));
strncpy(mystr, helloWorld, 12);
printf("%s\n", mystr);
}
|
很明显,这段程序中有内存上的错误,假设我们疏忽了这些错误,当我们使用Purify进行测试时,我们会发现这段程序中的内存错误在Purify下很容易就被找出来了。首先,我们要做的是使用Purify编译这段程序:
> purify gcc -g -o hello hello.c
Purify 2003.06.00 Solaris 2 (32-bit) Copyright (C) 1992-2002 Rational Software Corp.
All rights reserved.
Instrumenting: cckc6pUD.o Linking
记得加上“-g”的选项,不然,purify不能显示源程序。好了,现在在当前目录下产生了可执行文件——hello,在运行hello之前,我们还得注意,执行被Purify编译过的程序,有可能会出现X-Windows,所以请注意设置DISPLAY环境,如果你是在Windows的Telnet客户端下执行,那么你可以在Windows下装一个叫做Exceed的工具软件,它可以方便地把X-Window显示在你的Windows桌面上)
好了,我们现在执行hello程序,就可以看到下面的一个窗口:
<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype>
我们可以看到Purify的报告中有两个内存错误,一个是ABR(Array Bounds Read)——数组越界读,一个是12个字节的Memory Leaked,展开小三角符号,我们可以看到更为详细报告:
展开ABR错误后,我们可以看到,ABR错误的产生是由printf产生的,而产生错误的内存是mystr。通过观察,我们马上可以发现为会什么会出现ABR错误,原因是C/C++中的字符串都是以“\0”结尾的,而我们分配字符串时,应该要比实际长度多一,以存放结束符,而我们以后面调用的strncpy只拷贝了字符串的有效内容,并没有在字符串最后加上一个结束符。而系统调用printf输出字符串内容直至遇到结束符,所以当其访问到12个长度时,还没有发现结束,于是继续向下访问,于是就出现了ABR错误。
好了,让我们再来看看Memory Leaked的报告信息:
我们可以看到,Purify指出了那块内存出现了内存泄露,泄露了多少个字节。通过Purify的报告,再加上我们对C/C++基础的了解,我们立马知道mystr是在堆上分配的内存,所以必须要我们自己手动释放,查看程序,我们发现我们忘了free ( mystr )。
好了,现在我们可以根据Purify报告修改我们的程序了:
#include <stdio.h>
#include <malloc.h>
static char *helloWorld = "Hello, World";
main()
{
char *mystr = malloc(strlen(helloWorld)+1);
strncpy(mystr, helloWorld, 12);
mystr[12]=”\0”;
printf("%s\n", mystr);
free(mystr);
}
|
现在,我们再用Purify重新编译我们的程序,然后运行,我们可以看到Purify会报告没有任何的内存问题。其实,使用Purify很简单,在后面,我将对Purify的各种常用特性做比较全面的阐述。
四、 内存问题一览
下面是Purify所能检测到的内存信息表:
内存信息
|
描述
|
错误等级
|
ABR
|
Array Bounds Read 数组越界读
|
3级
|
ABW
|
Array Bounds Write 数组越界写
|
2级
|
BSR
|
Beyond Stack Read 越栈读
|
3级
|
BSW
|
Beyond Stack Write 越栈写
|
3级
|
COR
|
Core Dump Imminent 非法操作
|
1级
|
FIU
|
File Descriptors In Use 文件描述符被使用
|
4级
|
FMM
|
Freeing Mismatched Memory 释放错误内存
|
2级
|
FMR
|
Free Memory Read 对已释放内存读
|
3级
|
FMW
|
Free Memory Write 对已释放内存写
|
2级
|
FNH
|
Freeing Non Heap Memory 释放非堆内存
|
2级
|
FUM
|
Freeing Unallocated Memory 释放了没有分配的内存
|
2级
|
IPR
|
Invalid Pointer Read 非法指针读
|
1级
|
IPW
|
Invalid Pointer Write 非法指针写
|
1级
|
MAF
|
Malloc Failure 分配内存失败
|
4级
|
MIU
|
Memory In-Use 内存正在使用
|
4级
|
MLK
|
Memory Leak 内存泄露
|
3级
|
MRE
|
Malloc Reentrancy Error remalloc错
|
2级
|
MSE
|
Memory Segment Error 内存段错
|
3级
|
NPR
|
Null Pointer Read 空指针读
|
1级
|
NPW
|
Null Pointer Write 空指针写
|
1级
|
PAR
|
Bad Parameter 错误的参数
|
3级
|
PLK
|
Potential Leak 潜在的内存泄露
|
3级
|
SBR
|
Stack Array Bounds Read 栈数组越界读
|
3级
|
SBW
|
Stack Array Bounds Write 栈数级越界写
|
2级
|
SIG
|
Signal 信号
|
4级
|
SOF
|
Stack Overflow 栈溢出
|
3级
|
UMC
|
Uninitialized Memory Copy 对未初始化的内存进行拷贝
|
3级
|
UMR
|
Uninitialized Memory Read 对未初始化的内存读
|
3级
|
WPF
|
Watchpoint Free 释放被监控的内存
|
4级
|
WPM
|
Watchpoint Malloc 被监控的内存分配
|
4级
|
WPN
|
Watchpoint Entry 被监控的内存
|
4级
|
WPR
|
Watchpoint Read 被监控的内存读
|
4级
|
WPW
|
Watchpoint Write 被监控的内存写
|
4级
|
WPX
|
Watchpoint Exit 退出被监控的内存
|
4级
|
ZPR
|
Zero Page Read 零页面读
|
1级
|
ZPW
|
Zero Page Write 零页面写
|
1级
|
1级:致命错误。 2级:危险错误。 3级:警告信息 4级:提示信息(非错误)
<-上一页 下一页->
(版权所有,转载时请注明作者和出处)
分享到:
相关推荐
**Purify:C/C++内存问题的诊断与解决** Purify是IBM推出的一款强大的内存问题检测工具,专门用于C和C++编程语言。它能够帮助开发者在应用程序运行时发现并解决各种内存相关的问题,如内存泄漏、双重释放、非法访问...
五、文件描述符问题在上面的内存问题表中,对于大多数的内存问题来说,相信对于熟悉C/C++的程序员,并不陌生。有一些关于Watchpoint和文件描述符的内容,可能会让你看得比较模糊,对于Watchpoint,我会在后面讲述。...
内存检查工具:Purify, Valgrind - **资源链接**: - [Valgrind使用指南](http://www.cprogramming.com/debugging/valgrind.html) - [Purify简介](http://pages.cs.wisc.edu/~hasti/cs368/resources/purify.html...
08-05-01 Windows2000 服务器端应用程序开发设计指南-安全连接(3) 08-05-01 Windows2000 服务器端应用程序开发设计指南-附录 08-04-30 Windows Sockets 规范及应用 08-04-30 C/C++内存问题检查利器——Purify 08-...