下面是本文中的程序在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作為一種運行時分析軟件可以很好地幫助您發現忽略的內存問題,或成為軟件自動測試中的一個重要組成部分。
延伸閱讀
文章來源于領測軟件測試網 http://www.kjueaiud.com/