CC++内存问题检查利器—Purify (二)

    技术2022-05-11  90

     

    三、           示例

    假设我们现在有这样一段程序: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环境,如果你是在WindowsTelnet客户端下执行,那么你可以在Windows下装一个叫做Exceed的工具软件,它可以方便地把X-Window显示在你的Windows桌面上)

     

    好了,我们现在执行hello程序,就可以看到下面的一个窗口:

     

     

    我们可以看到Purify的报告中有两个内存错误,一个是ABRArray 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级:提示信息(非错误)

    <-上一页  下一页->

     

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

     

    最新回复(0)