




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、簡介本文介紹了IBM Rational Purify的基本概念和在不同操作系統(tǒng)中使用Purify對C/C+源程序中存在的內(nèi)存問題進(jìn)行勘察和分析,并且提供了有關(guān)的實例以便讀者在實際操作中作為參考?;仨撌?內(nèi)存問題的原因及分類在C/C+程序中,有關(guān)內(nèi)存使用的問題是最難發(fā)現(xiàn)和解決的。這些問題可能導(dǎo)致程序莫名其妙地停止、崩潰,或者不斷消耗內(nèi)存直至資源耗盡。由于C/C+語言本身的特質(zhì)和歷史原因,程序員使用內(nèi)存需要注意的事項較多,而且語言本身也不提供類似Java的垃圾清理機(jī)制。編程人員使用一定的工具來查找和調(diào)試內(nèi)存相關(guān)問題是十分必要的??偟恼f來,與內(nèi)存有關(guān)的問題可以分成兩類:內(nèi)存訪問錯誤和內(nèi)存使用錯誤。內(nèi)
2、存訪問錯誤包括錯誤地讀取內(nèi)存和錯誤地寫內(nèi)存。錯誤地讀取內(nèi)存可能讓你的模塊返回意想不到的結(jié)果,從而導(dǎo)致后續(xù)的模塊運行異常。錯誤地寫內(nèi)存可能導(dǎo)致系統(tǒng)崩潰。內(nèi)存使用方面的錯誤主要是指申請的內(nèi)存沒有正確釋放,從而使程序運行逐漸減慢,直至停止。這方面的錯誤由于表現(xiàn)比較慢很難被人工察覺。程序也許運行了很久才會耗凈資源,發(fā)生問題。1.1 內(nèi)存解剖一個典型的C+內(nèi)存布局如下圖所示:自底向上,內(nèi)存中依次存放著只讀的程序代碼和數(shù)據(jù),全局變量和靜態(tài)變量,堆中的動態(tài)申請變量和堆棧中的自動變量。自動變量就是在函數(shù)內(nèi)聲明的局部變量。當(dāng)函數(shù)被調(diào)用時,它們被壓入棧;當(dāng)函數(shù)返回時,它們就要被彈出堆棧。堆棧的使用基本上由系統(tǒng)控制
3、,用戶一般不會直接對其進(jìn)行控制,所以堆棧的使用還是相對安全的。動態(tài)內(nèi)存是一柄雙刃劍:它可以提供程序員更靈活的內(nèi)存使用方法,而且有些算法沒有動態(tài)內(nèi)存會很難實現(xiàn);但是動態(tài)內(nèi)存往往是內(nèi)存問題存在的沃土。1.2 內(nèi)存訪問錯誤相對用戶使用的語言,動態(tài)內(nèi)存的申請一般由malloc/new來完成,釋放由free/delete完成。基本的原則可以總結(jié)為:一對一,不混用。也就是說一個malloc必須對應(yīng)一且唯一的free;new對應(yīng)一且唯一的delete; malloc不能和delete, new不能和free對應(yīng)。另外在C+中要注意delete和delete的區(qū)別。delete用來釋放單元變量,delete用
4、來釋放數(shù)組等集聚變量。有關(guān)這方面的詳細(xì)信息可以參考C+Adv。我們可以將內(nèi)存訪問錯誤大致分成以下幾類:數(shù)組越界讀或?qū)?、訪問未初始化內(nèi)存、訪問已經(jīng)釋放的內(nèi)存和重復(fù)釋放內(nèi)存或釋放非法內(nèi)存。下面的代碼集中顯示了上述問題的典型例子:1 #include <iostream>2 using namespace std;3 int main()4 char* str1="four"5 char* str2=new char4;/not enough space6 char* str3=str2;7 cout<<str2<<endl;/UMR8 str
5、cpy(str2,str1);/ABW9 cout<<str2<<endl; /ABR10 delete str2;11 str20+=2;/FMR and FMW12 delete str3;/FFM13 由以上的程序,我們可以看到:在第5行分配內(nèi)存時,忽略了字符串終止符"0"所占空間導(dǎo)致了第8行的數(shù)組越界寫(Array Bounds Write)和第9行的數(shù)組越界讀(Array Bounds Read); 在第7行,打印尚未賦值的str2將產(chǎn)生訪問未初始化內(nèi)存錯誤(Uninitialized Memory Read);在第11行使用已經(jīng)釋放的變量
6、將導(dǎo)致釋放內(nèi)存讀和寫錯誤(Freed Memory Read and Freed Memory Write);最后由于str3和str2所指的是同一片內(nèi)存,第12行又一次釋放了已經(jīng)被釋放的空間 (Free Freed Memory)。這個包含許多錯誤的程序可以編譯連接,而且可以在很多平臺上運行。但是這些錯誤就像定時炸彈,會在特殊配置下觸發(fā),造成不可預(yù)見的錯誤。這就是內(nèi)存錯誤難以發(fā)現(xiàn)的一個主要原因。1.3 內(nèi)存使用錯誤內(nèi)存使用錯誤主要是指內(nèi)存泄漏,也就是指申請的動態(tài)內(nèi)存沒有被正確地釋放,或者是沒有指針可以訪問這些內(nèi)存。這些小的被人遺忘的內(nèi)存塊占據(jù)了一定的地址空間。當(dāng)系統(tǒng)壓力增大時,這些越來越多的
7、小塊將最終導(dǎo)致系統(tǒng)內(nèi)存耗盡。內(nèi)存使用錯誤比內(nèi)存訪問錯誤更加難以發(fā)現(xiàn)。這主要有兩點原因:第一,內(nèi)存使用錯誤是"慢性病",它的癥狀可能不會在少數(shù)、短時間的運行中體現(xiàn);第二,內(nèi)存使用錯誤是因為"不做為"(忘記釋放內(nèi)存)而不是"做錯"造成的。這樣由于忽略造成的錯誤在檢查局部代碼時很難發(fā)現(xiàn),尤其是當(dāng)系統(tǒng)相當(dāng)復(fù)雜的時候?;仨撌?Purify的原理及使用IBM Rational PurifyPlus是一組程序運行時的分析軟件。她包括了程序性能瓶頸分析軟件Quantify, 程序覆蓋面分析軟件PureCoverage,和本文的主角:程序運行錯誤分析軟
8、件Purify。Purify可以發(fā)現(xiàn)程序運行時的內(nèi)存訪問,內(nèi)存泄漏和其他難以發(fā)現(xiàn)的問題。同時她也是市場上唯一支持多種平臺的類似工具,并且可以和很多主流開發(fā)工具集成。Purify可以檢查應(yīng)用的每一個模塊,甚至可以查出復(fù)雜的多線程或進(jìn)程應(yīng)用中的錯誤。另外她不僅可以檢查C/C+,還可以對Java或.NET中的內(nèi)存泄漏問題給出報告。2.1 Purify的原理程序運行時的分析可以采用多種方法。Purify使用了具有專利的目標(biāo)代碼插入技術(shù)(OCI:Object Code Insertion)。她在程序的目標(biāo)代碼中插入了特殊的指令用來檢查內(nèi)存的狀態(tài)和使用情況。這樣做的好處是不需要修改源代碼,只需要重新編譯就
9、可以對程序進(jìn)行分析。對于所有程序中使用的動態(tài)內(nèi)存,Purify將它們按照狀態(tài)進(jìn)行歸類。這可以由下圖來說明(來自DEV205):參見本文中以上給出的代碼,在程序第5行執(zhí)行后,str2處于黃色狀態(tài)。當(dāng)在第7行進(jìn)行讀的時候,系統(tǒng)就會報告一個訪問未初始化內(nèi)存錯誤(Uninitialized Memory Read)。因為只有在綠色狀態(tài)下,內(nèi)存才可以被合法訪問。為了檢查數(shù)據(jù)越界錯誤(ABR,ABW),Purify還在每個分配的內(nèi)存前后插入了紅色區(qū)域。這樣一來,超過邊界的訪問指令必定落在非法區(qū)域,從而觸發(fā)ABR或者ABW錯誤報告。這里需要指出一點。訪問未初始化內(nèi)存錯誤UMR在某些情況下其實是合法的操作,例
10、如內(nèi)存拷貝。所以在分析報告時可以把UMR放到最后,或者干脆從結(jié)果中濾除。2.2 Purify的使用這里簡單介紹一下Purify在Windows和UNIX環(huán)境下的使用。在Windows中,只要運行Purify,填入需要分析的程序及參數(shù)就可。Purify會自動插入檢測代碼并顯示報告。報告的格式如下(來自DEV205):藍(lán)色的圖標(biāo)代表一些運行的信息,比如開始和結(jié)束等。黃色是Purify給出的警告。通常UMR會作為警告列出。紅色則代表嚴(yán)重的錯誤。每一種相同的錯誤,尤其是在循環(huán)中的,會被集中在一起顯示,并且標(biāo)明發(fā)生的次數(shù)。由每個錯誤的詳細(xì)信息,用戶可以知道相應(yīng)的內(nèi)存地址和源代碼的位置,并直接修改。另外用
11、戶還可以設(shè)置不同的濾過器,用來隱藏暫時不關(guān)心的消息。在UNIX系統(tǒng)中,使用Purify需要重新編譯程序。通常的做法是修改Makefile中的編譯器變量。下面是用來編譯本文中程序的Makefile: CC=purify gccall: pplusdemopplusdemo: pplusdemo.o $(CC) -o pplusdemo pplusdemo.o -lstdc+pplusdemo.o: pplusdemo.cpp $(CC) -g -c -w pplusdemo.cppclean: -rm pplusdemo pplusdemo.o 首先運行Purify安裝目錄下的purifyplu
12、s_setup.sh來設(shè)置環(huán)境變量,然后運行make重新編譯程序。需要指出的是,程序必須編譯成調(diào)試版本。在gcc中,也就是必須使用"-g"選項。在重新編譯的程序運行結(jié)束后,Purify會打印出一個分析報告。它的格式和含義與Windows平臺大同小異。下面是本文中的程序在Linux上Purify運行的結(jié)果: * Purify instrumented ./pplusdemo (pid 30669) *UMR: Uninitialized memory read: * This is occurring while in:strlen rtlib.ostd:basic_ostr
13、eam< char,std:char_traits< char>> & std:operator<<<std:char_traits< char>>(std:basic_ostream< char,std:char_traits<char>> &, char const *) libstdc+.so.5main pplusdemo.cpp:7_libc_start_main libc.so.6_start crt1.o * Reading 1 byte from 0x80b45e0 in the
14、 heap. * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes. * This block was allocated from:malloc rtlib.ooperator new( unsigned) libstdc+.so.5operator new ( unsigned) libstdc+.so.5main pplusdemo.cpp:5_libc_start_main libc.so.6_start crt1.o* Purify instrumented ./pplusdemo (pi
15、d 30669) *ABW: Array bounds write: * This is occurring while in:strcpy rtlib.omain 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
16、 was allocated from:malloc rtlib.ooperator new( unsigned) libstdc+.so.5operator new ( unsigned) libstdc+.so.5main 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.ostd:basic_ostream&
17、lt; char,std:char_traits< char>> & std:operator<<<std:char_traits< char>>(std:basic_ostream< char,std:char_traits<char>> &, char const *) libstdc+.so.5main pplusdemo.cpp:9_libc_start_main libc.so.6_start crt1.o * Reading 5 bytes from 0x80b45e0 in the he
18、ap (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.ooperator new( unsigned) libstdc+.so.5operator new ( unsigned) libstdc+.so.5main pplusdemo.cpp:5_libc_start_main libc.so.6_start crt1.o* Purify i
19、nstrumented ./pplusdemo (pid 30669) *FMM: Freeing mismatched memory: * This is occurring while in:operator delete( void *) rtlib.omain 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'
20、d block of 4 bytes. * This block was allocated from:malloc rtlib.ooperator new( unsigned) libstdc+.so.5operator new ( unsigned) libstdc+.so.5main 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 ro
21、utine 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
22、bytes. * This block was allocated from:malloc rtlib.ooperator new( unsigned) libstdc+.so.5operator new ( unsigned) libstdc+.so.5main 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.5main pplusdemo.cpp:10_
23、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 o
24、f 4 bytes. * This block was allocated from:malloc rtlib.ooperator new( unsigned) libstdc+.so.5operator new ( unsigned) libstdc+.so.5main 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.5main pplusdemo.cpp
25、: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.5main pplusdemo.cpp:12_libc_start_main libc.so.6_start crt1.o * Attempting to free block at 0x80b45e0 already freed. *
26、 This block was allocated from:malloc rtlib.ooperator new( unsigned) libstdc+.so.5operator new ( unsigned) libstdc+.so.5main 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.5main pplusdemo.cpp:10_libc_sta
27、rt_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 d
28、escriptor 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
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 西安郵電大學(xué)《美術(shù)鑒賞與批評》2023-2024學(xué)年第二學(xué)期期末試卷
- 浙江理工大學(xué)《木材工業(yè)自動化》2023-2024學(xué)年第二學(xué)期期末試卷
- 南昌大學(xué)共青學(xué)院《免疫學(xué)與病原生物學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 撫順師范高等??茖W(xué)校《品牌形象專項設(shè)計一》2023-2024學(xué)年第二學(xué)期期末試卷
- 證券從業(yè)資格證券投資顧問勝任能力考試證券投資顧問業(yè)務(wù)真題1
- 山東勞動職業(yè)技術(shù)學(xué)院《智能車輛環(huán)境感知技術(shù)》2023-2024學(xué)年第二學(xué)期期末試卷
- 2025遼寧省安全員B證(項目經(jīng)理)考試題庫
- 湖南冶金職業(yè)技術(shù)學(xué)院《企業(yè)生產(chǎn)與技術(shù)管理》2023-2024學(xué)年第二學(xué)期期末試卷
- 2025年陜西省建筑安全員-B證(項目經(jīng)理)考試題庫
- 湖南電氣職業(yè)技術(shù)學(xué)院《面向數(shù)據(jù)科學(xué)的語言》2023-2024學(xué)年第二學(xué)期期末試卷
- 2024年1月浙江省首考普通高等學(xué)校招生全國統(tǒng)一考試英語試題
- 關(guān)于新能源場站“兩個細(xì)則”的影響和管理措施
- 手術(shù)部位感染預(yù)防控制措施
- 社會學(xué)概論課件
- 中醫(yī)類診所規(guī)章制度與崗位職責(zé)
- 初中語文 中考總復(fù)習(xí)-文言文斷句訓(xùn)練120題(含答案解析)
- 影視鑒賞-動畫電影課件
- 美學(xué)原理全套教學(xué)課件
- 精裝修施工圖深化內(nèi)容及要求
- 《克雷洛夫寓言》閱讀指導(dǎo)課件
- 《無人機(jī)載荷與行業(yè)應(yīng)用》 課件全套 第1-6章 無人機(jī)任務(wù)載荷系統(tǒng)概述- 未來展望與挑戰(zhàn)
評論
0/150
提交評論