下面是本文中的程序在Linux上Purify运行的结果:
**** Purify instrumented ./pplusdemo (pid 30669) ****UMR: Uninitialized memory read: * This is occurring while in: strlen [rtlib.o] std::basic_ostream< char,std::char_traits< char>> & std::operator <<<std::char_traits< char>>(std::basic_ostream< char,std::char_traits< char>> &, char const *) [libstdc++.so.5] main [pplusdemo.cpp:7] __libc_start_main [libc.so.6] _start [crt1.o] * Reading 1 byte from 0x80b45e0 in the heap. * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o]**** Purify instrumented ./pplusdemo (pid 30669) ****ABW: Array bounds write: * This is occurring while in: strcpy [rtlib.o] main [pplusdemo.cpp:8] __libc_start_main [libc.so.6] _start [crt1.o] * Writing 5 bytes to 0x80b45e0 in the heap (1 byte at 0x80b45e4 illegal). * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o]**** Purify instrumented ./pplusdemo (pid 30669) ****ABR: Array bounds read: * This is occurring while in: strlen [rtlib.o] std::basic_ostream< char,std::char_traits< char>> & std::operator <<<std::char_traits< char>>(std::basic_ostream< char,std::char_traits< char>> &, char const *) [libstdc++.so.5] main [pplusdemo.cpp:9] __libc_start_main [libc.so.6] _start [crt1.o] * Reading 5 bytes from 0x80b45e0 in the heap (1 byte at 0x80b45e4 illegal). * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o]**** Purify instrumented ./pplusdemo (pid 30669) ****FMM: Freeing mismatched memory: * This is occurring while in: operator delete( void *) [rtlib.o] main [pplusdemo.cpp:10] __libc_start_main [libc.so.6] _start [crt1.o] * Attempting to free block at 0x80b45e0 in the heap. * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o] * This block of memory was obtained using an allocation routine which is not compatible with the routine by which it is being freed.**** Purify instrumented ./pplusdemo (pid 30669) ****FMR: Free memory read: * This is occurring while in: main [pplusdemo.cpp:11] __libc_start_main [libc.so.6] _start [crt1.o] * Reading 1 byte from 0x80b45e0 in the heap. * Address 0x80b45e0 is at the beginning of a freed block of 4 bytes. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o] * There have been 0 frees since this block was freed from: free [rtlib.o] _ZdLpV [libstdc++.so.5] main [pplusdemo.cpp:10] __libc_start_main [libc.so.6] _start [crt1.o]**** Purify instrumented ./pplusdemo (pid 30669) ****FMW: Free memory write: * This is occurring while in: main [pplusdemo.cpp:11] __libc_start_main [libc.so.6] _start [crt1.o] * Writing 1 byte to 0x80b45e0 in the heap. * Address 0x80b45e0 is at the beginning of a freed block of 4 bytes. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o] * There have been 0 frees since this block was freed from: free [rtlib.o] _ZdLpV [libstdc++.so.5] main [pplusdemo.cpp:10] __libc_start_main [libc.so.6] _start [crt1.o]**** Purify instrumented ./pplusdemo (pid 30669) ****FUM: Freeing unallocated memory: * This is occurring while in: free [rtlib.o] _ZdLpV [libstdc++.so.5] main [pplusdemo.cpp:12] __libc_start_main [libc.so.6] _start [crt1.o] * Attempting to free block at 0x80b45e0 already freed. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o] * There have been 1 frees since this block was freed from: free [rtlib.o] _ZdLpV [libstdc++.so.5] main [pplusdemo.cpp:10] __libc_start_main [libc.so.6] _start [crt1.o]**** Purify instrumented ./pplusdemo (pid 30669) ****Current file descriptors in use: 5FIU: file descriptor 0: <stdin>FIU: file descriptor 1: <stdout>FIU: file descriptor 2: <stderr>FIU: file descriptor 26: <reserved for Purify internal use>FIU: file descriptor 27: <reserved for Purify internal use>**** Purify instrumented ./pplusdemo (pid 30669) ****Purify: Searching for all memory leaks...Memory leaked: 0 bytes (0%); potentially leaked: 0 bytes (0%)Purify Heap Analysis (combining suppressed and unsuppressed blocks) Blocks Bytes Leaked 0 0 Potentially Leaked 0 0 In-Use 0 0 ---------------------------------------- Total Allocated 0 0**** Purify instrumented ./pplusdemo (pid 30669) **** * Program exited with status code 0. * 7 access errors, 7 total occurrences. * 0 bytes leaked. * 0 bytes potentially leaked. * Basic memory usage (including Purify overhead): 290012 code 152928 data/bss 6816 heap (peak use) 7800 stack
我们对照程序可以发现Purify查出了程序中所有的错误。对于每个错误,她不但给出了源代码的位置还指出这些内存最初分配的源代码位置。这对于查找问题提供了很大帮助。对于程序12行的解释,Purify将其认为是不匹配的内存释放(FMM: Freeing mismatched memory),因为她认为这样的释放方式不符合严格的规定。
Purify在其报告和文档中使用了很多的缩写,在此一并列出,以便读者在使用时参考(来自[Purify]):
2.3 Purify的一些特性
这里简单介绍一下Purify提供的几个特性。有关这些特性的详细信息,请查阅文档[Purify]。
观察点(Watchpoint):通过在程序或者调试器中调用Purify 提供的观察点函数,Purify可以报告有关被观察对象的读写或其他操作。与Rational其他产品的集成:在Puify的用户界面中可以方便地进入ClearCase和ClearQuest。Purify还可以和PureCoverage同时使用,对程序进行分析。 Purify的定制:无论是Purify报告中的消息,还是界面中的元素,都可以进行一定程度的定制。另外通过修改配置文件和调用Purify API,用户还可以自动记录运行日志,发送电子邮件等。 Purify提供的API:为了更好地把Purify融合到自动化测试的体系中,Purify提供了一系列的公开函数。用户完全可以通过脚本的方式自动运行,记录,和分析Purify。3.总结
当使用C/C++进行开发时,采用良好的一致的编程规范是防止内存问题第一道也是最重要的措施。在此前提下,IBM Rational Purify作为一种运行时分析软件可以很好地帮助您发现忽略的内存问题,或成为软件自动测试中的一个重要组成部分。
延伸阅读
文章来源于领测软件测试网 https://www.ltesting.net/