五、             文件描述符问题

在上面的内存问题表中,对于大多数的内存问题来说,相信对于熟悉C/C++的程序员,并不陌生。有一些关于Watchpoint和文件描述符的内容,可能会让你看得比较模糊,对于Watchpoint,我会在后面讲述。这一节,我就一个示例说一说文件描述述问题是如何产生的,并由此介绍一下Purify的一些特性。
先查看下面这段程序:
#include <stdio.h>
main()
{
FILE* fp;
int num;
fp = fopen("./test.txt", "r");
if ( fp == NULL){
perror("Error:");
exit(-1);
}
fscanf(fp, "%d", &num);
if ( num < 0 ){
printf("Error: the num should be greater than 0!\n");
exit(-1);
}
fclose(fp);
}
在当前目录下建一个test.txt的文件,并设置其内容为-20。使用Purify编译并运行程序:
>  purify gcc -g -o testfd testfd.c
Purify 2003.06.00 Solaris 2 (32-bit) Copyright (C) 1992-2002 Rational Software Corp.  All rights reserved. 
Instrumenting: ccqqF6pY.o  Linking
>./testfd
出现以下画面:
 
由图中,我们可以看到,Purify报告有FIU错误,意思是,我们在程序退出时,没有关闭文件描述符。还有一些算是安全的文件描述符信息,那就是关于0,1,2这三个标准文件描述符的FIU,这些信息是正常的,所以在其前面也就没有小三角符号了。
通过这个例子,我们可以看到,Purify不但可以找到内存的操作错误,还可以找到文件描述符的错误。
如果你不想让Purify显示FIU信息,你可以设置Purify的 -fds-inuse-at-exit=no 选项,如:
 
>  purify –fds-inuse-at-exit gcc -g -o testfd testfd.c
或者使用Purify的API函数 purify_clear_fds_inuse 来阻止显示,你可以在你的程序中调用Purify的API函数。有关Purify的API函数的细节,我会在后面给你讲述。
 
 

六、             控制Purify的输出

1、产生ASCII文本文件
在默认情况下,Purify会显示出一个图形窗口来报告信息。当然,如果你的环境所限,你不想Purify出现图形界面,只是生成文本文件来报告,能过设置Purify的参数,你可以很容易做到这一点。
在程序编译时,你只需简单的调置Purify的编译参数 –windows=no 即可做到,如:
> purify –windows=no gcc –g –o hello hello.c
Purify会把其报告信息写到标准错误设备上,在文本方式下,Purify就不报告同种错误出现在个数,而只是报告的信息了。
我们可以使用两种方式让Purify的信息输出到文本文件中。
第一种是使用操作系统的重定向功能,如:
在csh下: % a.out.pure >& a.out.messages
在sh和ksh下: $ a.out.pure 2> a.out.messages
第二种是指定Purify的日志文件参数,如:
-log-file=<filename>.plog
下面,是一个Purify生成的ASCII文本文件的样子:
> ./hello
****  Purify instrumented hello (pid 25698 at Wed Dec 10 22:29:33 2003)
  * Purify 2003.06.00 Solaris 2 (32-bit) Copyright (C) 1992-2002 Rational Software Corp.  All rights reserved. 
  * For contact information type: "purify -help"
  * Options settings: -follow-child-processes=yes -purify -windows=no \
    -purify-home=/usr/rational/releases/purify.sol.2003.06.00 \
    -gcc3_path=/usr/local/bin/gcc \
    -cache-dir=/usr/rational/releases/purify.sol.2003.06.00/cache \
    -demangle_program=/usr/local/bin/c++filt
  * License successfully checked out.
  * Command-line: ./hello
 
****  Purify instrumented hello (pid 25698)  ****
ABR: Array bounds read:
  * This is occurring while in:
        strlen         [rtlib.o]
        _doprnt        [libc.so.1]
        printf         [libc.so.1]
        main           [hello.c:11]
        _start         [crt1.o]
  * Reading 13 bytes from 0x8ea08 in the heap (1 byte at 0x8ea14 illegal).
  * Address 0x8ea08 is at the beginning of a malloc'd block of 12 bytes.
  * This block was allocated from:
        malloc         [rtlib.o]
        main           [hello.c:8]
        _start         [crt1.o]
Hello, World
 
****  Purify instrumented hello (pid 25698)  ****
Current file de.ors in use: 5
FIU: file de.or 0: <stdin>
FIU: file de.or 1: <stdout>
FIU: file de.or 2: <stderr>
FIU: file de.or 26: <reserved for Purify internal use>
FIU: file de.or 27: <reserved for Purify internal use>
 
****  Purify instrumented hello (pid 25698)  ****
Purify: Searching for all memory leaks...
 
Memory leaked: 12 bytes (100%); potentially leaked: 0 bytes (0%)
 
MLK: 12 bytes leaked at 0x8ea08
  * This memory was allocated from:
        malloc         [rtlib.o]
        main           [hello.c:8]
        _start         [crt1.o]
 
Purify Heap Analysis (combining suppressed and unsuppressed blocks)
                         Blocks        Bytes
              Leaked          1           12
  Potentially Leaked          0            0
              In-Use          0            0
  ----------------------------------------
     Total Allocated          1           12
 
****  Purify instrumented hello (pid 25698)  ****
  * Program exited with status code 13.
  * 1 access error, 1 total occurrence.
  * 12 bytes leaked.
  * 0 bytes potentially leaked.
  * Basic memory usage (including Purify overhead):
    351348 code
    101724 data/bss
    8192 heap (peak use)
    1272 stack
  * Shared library memory usage (including Purify overhead):
    992 libpure_solaris2_init.so.1 (shared code)
    280 libpure_solaris2_init.so.1 (private data)
    1079516 libc.so.1_pure_p3_c0_111202132_58_32_1158500S (shared code)
    31404 libc.so.1_pure_p3_c0_111202132_58_32_1158500S (private data)
    2324 libdl.so.1_pure_p3_c0_111202132_58_32_4624S (shared code)
    4 libdl.so.1_pure_p3_c0_111202132_58_32_4624S (private data)
    14048 libinternal_stubs.so.1 (shared code)
    940 libinternal_stubs.so.1 (private data)
 
2、产生Purify自己的文件
通过查看ASCII文本文件,我们发现其很不容易查看,特别是当错误很多时,而用在文件中没有源代码,看起来就是不如图形界面的好。但是我们为了把Purify的报告信息通过电子邮件传送给别人查看时,文件和图形界面兼得,我们可以使用Purify自己的文件,叫Purify View文件。我们可以使用Purify的图形界面打开这个文件,而来在图形化的窗口下查看。
我们可以有两种方式得到这个文件。一种是在Purify的图形界面的菜单中点击“File -> Save as”来生成。第二种方法是使用Purify的 -view-file=<filename>.pv 参数来设置Purify View文件。
而要打开这个文件时,要么简单地在Purify的菜单中选取“Open”菜单,要么使用这样的命令:
% purify –view <filename>.pv
3、自动发送邮件
使用Purify的-mail-to-user参数可以方便地让Purify自动发送报告邮件。如:
% purify -mail-to-user=chris  gcc ...
% purify -mail-to-user=chris,pat  gcc ...
% purify -mail-to-user=devgrp  gcc ...
在默认情况下,只要你设置了这个参数,Purify是不会打开图形界面窗口的,如果你要Purify打开图形窗口,那么你就一同使用 –windows=yes 参数。
4、输出自己的信息
如果你想在Purify中输出自己的信息,你可以在你的程序中使用Purify的API函数:
l         purify_printf(const char *fmt, ...)  使用这个函数可以在Purify的图形界面,文件文件中输出你的自己的信息。
l         purify_logfile_printf(const char *fmt, ...)  使用这个函数可以在Purify的ASCII文本文件中输出你自己的信息。
l         purify_printf_with_call_chain(const char *fmt, ...) 使用这个函数可以在Purify的输出的同时,打印出函数调用栈的信息。这个函数和purify_printf很类似。
注意,以上三个函数和标准C中的printf函数几乎是一样的,不过,这几个函数并不支持像printf函数中的所有%的格式,它仅支持:%d,%u, %n,%s, %c, %e, %f, 和 %g 这几种格式,并且就 %e %f %g 而且,并不支持其精度定义。

本文转自 haoel 51CTO博客,原文链接:http://blog.51cto.com/haoel/124671,如需转载请自行联系原作者

C/C++内存问题检查利器—Purify (三)相关推荐

  1. C/C++内存问题检查利器——Purify

    C/C++内存问题检查利器--Purify 一.           引言 我们都知道软件的测试(在以产品为主的软件公司中叫做QA-Quality Assessment)占了整个软件工程的30% -5 ...

  2. 内存问题检查利器——Purify

    内存问题检查利器--Purify https://www.cnblogs.com/Leo_wl/p/7699489.html 一.           引言 我们都知道软件的测试(在以产品为主的软件公 ...

  3. C/C++内存问题检查利器—Purify (一)

    C/C++内存问题检查利器--Purify 陈皓 一.           引言 我们都知道软件的测试(在以产品为主的软件公司中叫做QA-Quality Assessment)占了整个软件工程的30% ...

  4. C/C++内存问题检查利器—Purify

    文章转自:http://blog.csdn.net/haoel/article/details/2900 一.           引言 我们都知道软件的测试(在以产品为主的软件公司中叫做QA-Qua ...

  5. C/C++内存问题检查利器—Purify (二)

    三.           示例 假设我们现在有这样一段程序:hello.c #include <stdio.h> #include <malloc.h>   static ch ...

  6. C/C++内存问题检查利器—Purify (四)

    七.             Purify的退出码 像UNIX下的软件,一般都会提供和别的应用程序的接口,像上面的生成文本文件,也是给别的应用程序提供接口的一种方式.这里,我们所要讲述的是Purify ...

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

    十.             设置WatchPoint 你可以在你的程序中,对你所想监控的程序设置一些WatchPoint,以方便于你对程序进行调试,或更容易找出问题的原因.就像我前面说,Purify ...

  8. 检查内存泄露的利器--VLD使用指南

    1. VLD简介 Visual Leak Detector是一个免费的,强大的,开源的,可视化C ++内存泄漏检测工具. VLD容易使用.安装后,只需告诉Visual C ++在哪里可以找到包含的头文 ...

  9. Windows内存管理学习笔记(三)—— 无处不在的缺页异常

    Windows内存管理学习笔记(三)-- 无处不在的缺页异常 缺页异常 实验一:设置虚拟内存 无处不在的缺页 位于页面文件 保留与提交的误区 实验二:理解缺页异常 EXECUTE_WRITECOPY ...

最新文章

  1. ISP算法高水平分析(上)
  2. [HTTP协议]入门篇
  3. [置顶] AMF序列化为对象和AMF序列化为二进制字节流
  4. 李永乐线性代数2020年强化课手写笔记汇总
  5. C++面向对象设计原则详解
  6. 血的案例告诫 | 模拟大批量数据测试边界上限
  7. 移动Web开发基础概念
  8. TensorFlow中的Nan值的陷阱
  9. ROS中阶笔记(二):机器人系统设计—URDF机器人建模
  10. docker -v 文件夹下没有数据_微服务就是Dubbo?并没有那么简单!微服务架构+Docker+k8s了解下...
  11. Cocos2d-x之MenuItem
  12. 未能加载文件或程序集“Enyim.Caching”或它的某一个依赖项。未能验证强名称签名...
  13. rest规范 ; restful 风格; gradel介绍 ; idea安装 ;
  14. PHP使用MQ消息队列
  15. Winform UI界面设计例程——多线程访问UI控件
  16. 操作系统:作业调度算法--短作业优先
  17. 类型多样的游戏模型3d模型素材,速来收藏
  18. LSTM之父最新长文:现代AI和深度学习发展史
  19. 【译】3D打印:介绍
  20. BUCT 程序设计基础第三篇20~30算法题答案(上)

热门文章

  1. SpringBoot项目改名字(或者别的操作)导致Maven项目中的application.yml没有绿叶
  2. 2007年通过做调查你一样能获得比较稳定的收入
  3. 前端面试知识点整理——项目整理
  4. 如何使用ppt导出高清的论文插图
  5. 手把手教学,带你在Linux、OS X、Windows下Docker的安装
  6. scrollTop是什么及用法说明
  7. 20多行js实现canvas雪夜下雪效果
  8. 充值系列——充值系统业务逻辑层实现(三)
  9. bootstrap的popover呈现table
  10. 服装产业发展趋势|供应链|智能制造