內(nèi)存檢測實例_第1頁
內(nèi)存檢測實例_第2頁
內(nèi)存檢測實例_第3頁
內(nèi)存檢測實例_第4頁
內(nèi)存檢測實例_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

DrMemory內(nèi)存檢測實例:Dr.Memory建立在DynamoRIO這個動態(tài)二進制插樁平臺上。動態(tài)監(jiān)測程序的運行,并對內(nèi)存訪問相關(guān)的執(zhí)行代碼進行動態(tài)修改,記錄其行為,并采用先進的算法進行錯誤檢查。根據(jù)DrMemory開發(fā)人員發(fā)表在CGO2011上的論文PracticalMemoryCheckingwithDr.Memory,DrMemory對程序的正常執(zhí)行影響較小,這在同類工具中是比較領(lǐng)先的。其performance和Valgrind的比較如圖1所示(圖片源自DrMemory主頁):圖1.和Valgrind的性能比較Valgrind對程序的正常運行影響較大,一般來說如果進行全面內(nèi)存檢測,會使程序的運行速度有50到300倍的減慢。而DrMemory在這個方面則有一定的優(yōu)勢。易用性和性能是DrMemory的主要優(yōu)點,此外DrMemory可以用于調(diào)試Windows程序,因此它被廣泛認為是Windows上的Valgrind替代工具。在Linux平臺中,DrMemory也往往可以作為Valgrind之外的另一個選擇。DrMemory對內(nèi)存泄露的監(jiān)測采用了比較獨特的算法,大量減少了”falsepositive”,即虛假錯誤。如果您使用Valgrind等工具后仍無法找到程序中的內(nèi)存錯誤,不妨試試DrMemory吧。Windows上DrMemory提供了可執(zhí)行安裝包,只需點擊下一步,即可安裝完畢。DrMemory,第一印象DrMemory的使用很簡單,可以說它是傻瓜式。正常運行一個程序時,我們在shell中敲入命令然后回車。為了用DrMemory檢查,只需要在HelloDrMemory,第一印象DrMemory的使用很簡單,可以說它是傻瓜式。正常運行一個程序時,我們在shell中敲入命令然后回車。為了用DrMemory檢查,只需要在正常命令之前加入drmemory.pl,比如程序檢查程序t,那么就這樣:drmemory.pl

./t在計算機領(lǐng)域,Helloworld總是第一個程序。讓我們寫一個HelloDrMemory,來和DrMemory簡單接觸一下吧。清單1,HelloDrMem例子程序1:

int

main()

2:

{

3:

char

*ptr;

4:

int

i;

5:

for(i=0;i<100;i++)

6:

{

7:

ptr=(char*)malloc(i);

8:

if(i%2)

free(ptr);

9:

}

10:

return

0;

11:

}很明顯,有50個內(nèi)存泄露,都在同一行代碼中(Line8)。讓我們用DrMemory來檢查它。屏幕上會有如上所示的錯誤匯總,注意看ERRORSFOUND下面的第5行:”50totalleaks”。不錯吧。根據(jù)提示,更多的細節(jié)被寫入一個result文本文件。打開并查看該文件,就可以知道程序在哪里出現(xiàn)了內(nèi)存錯誤了。真是太方便了。不過result文件是否容易閱讀呢?下面我們來詳細解釋如何閱讀DrMemory產(chǎn)生的result文件。DrMemory報告解讀細節(jié)內(nèi)存非法訪問DrMemory認為任何對未分配內(nèi)存區(qū)域的讀寫都是非法的。在Linux中,應(yīng)用程序可以用以下幾個方式分配內(nèi)存:調(diào)用mmap(或者mremap)調(diào)用malloc在堆上分配內(nèi)存使用alloca在棧上分配內(nèi)存非法訪問就是對以上三種方法分配的內(nèi)存區(qū)域之外進行的訪問。常見的問題包括bufferoverflow、數(shù)組越界、讀寫已經(jīng)free的內(nèi)存、堆棧溢出等等。讓我們測試下面這個問題程序。Bufferoverflow例子程序的第5到6行存在bufferoverflow。在內(nèi)存中,buffer的分布如下圖所示:圖2.Buffer分布訪問x+8將產(chǎn)生一個非法內(nèi)存訪問。對此,DrMemory將給出如下的錯誤信息:首先用大寫的單詞UNADDRESSABLEACCESS表明這是一個非法訪問錯誤。接著,“reading0x0804a020-0x0804a0211byte(s)”表示這是一個非法讀,讀取的范圍為0x0804a020到0x0804a021,一共讀了1個byte。接下來的三行是調(diào)用堆棧信息,可以方便地看到錯誤發(fā)生在哪個源文件的哪一行(程序t需要在用gcc編譯的時候給定-g選項)。此外DrMemory還給出了一些輔助的錯誤信息。比如:錯誤發(fā)生的時間:Note:elapsedtime=0:00:00.133inthread13971。這表明錯誤是程序開始的第0.133秒后發(fā)生的,有些情況下,人們可以根據(jù)這個時間進行輔助判斷。錯誤細節(jié):Note:refersto1byte(s)beyondlastvalidbyteinpriormalloc。這里給出了錯誤的詳細信息,如前所述,造成非法訪問的可能很多,在本例中是bufferoverflow,因此這里的詳細信息可以幫助我們了解非法訪問的具體原因。Note:prevlowermalloc:0x0804a018-0x0804a020。這里給出了overflow之前的合法內(nèi)存地址,有些情況下對于查錯有一定的幫助。Note:instruction:movzx(%eax)->%eax。這里給出的是造成錯誤的具體指令??梢钥吹紻rMemory只報告了一個未初始化讀錯誤,在第12行。很多其他工具對于memcpy(&b,&a,sizeof(T))也會報錯。GCC將自動對齊數(shù)據(jù)結(jié)構(gòu)(未使用pack修飾符的情況下)。因此structT在內(nèi)存中的實際分布如下:圖3.內(nèi)存拷貝細節(jié)在memcpy時,有3個未初始化byte也被訪問了,但這類錯誤如果也報告的話,對正常程序DrMemory會產(chǎn)生很多錯誤信息。這些其實不是錯誤,所以被稱為FalsePositive。類似醫(yī)學(xué)名詞“假陽性”。內(nèi)存調(diào)試工具的一個主要目標(biāo)就是減少FalsePositive,否則產(chǎn)生的報告有用性將極大降低。其它很多工具,遇到上述拷貝會報告falsepositive,浪費讀報告的人們的時間。因此這是DrMemory的一個重要優(yōu)點。內(nèi)存泄露內(nèi)存泄露是常見的內(nèi)存錯誤,我們可能都曾經(jīng)遇到過。不過Dr.Memory對內(nèi)存泄露的定義比較獨特,在程序退出之前,Dr.Memory把所有依然被分配的內(nèi)存分為三類:Still-reachableallocation很多程序分配了內(nèi)存之后,在其整個生命周期內(nèi)都不釋放。雖然這是一種泄露,但實際上多數(shù)情況下這是無害的,甚至是特意這樣設(shè)計的。因此Dr.Memory并不認為這是一種內(nèi)存泄露,而稱之為”Still-reachableallocation”。Leak有一些內(nèi)存無法再被釋放,因為指向該內(nèi)存的指針丟失了。比如下面這個代碼:清單5.內(nèi)存Leak例子代碼DrMemory稱這類錯誤為內(nèi)存泄露。因為這些內(nèi)存已經(jīng)沒有辦法被釋放了。PossibleLeak如前所述指向內(nèi)存的指針被修改會被認為是一個Leak,但并非所有的指針修改都是一個Leak。DrMemory利用一些經(jīng)驗規(guī)則(Heuristic)將以下幾種指針修改列為PossibleLeak。第一種情況:C++程序利用new[]分配了一個數(shù)組,該數(shù)組的每個元素都是擁有自己的析構(gòu)函數(shù)的復(fù)雜數(shù)據(jù)結(jié)構(gòu)。這種情況下,New操作符為每個元素加上一個header用來保存數(shù)組的個數(shù),以便delete[]操作符知道需要調(diào)用多少個析構(gòu)函數(shù)。但new[]返回caller的是header之后的地址,這樣就變成了一個mid-allocation指針。這可能被Drmemory認為是一個內(nèi)存泄露。但可以使用-no_midchunk_new_ok選項讓DrMemory將這類錯誤報告為”possibleleak”而非”leak”。參考下圖,理解這種情況。圖4.mid-chunknew從堆分配器的角度來看,buffer的起點在A處,但new返回B,給Object變量賦值。從某種角度上看,指針A丟失了,是一個leak,但實際上,當(dāng)調(diào)用delete[]操作符時,C++運行時庫會自動將Object指針減4,從而指向A點,再進行釋放。某些編譯器不使用這種做法,則沒有這個問題。第二種情況,某些C++編譯器在處理多繼承時,會出現(xiàn)mid-chunk指針。很抱歉,具體細節(jié)本人也不甚了解。DrMemory的原文如下:itincludesinstancesofapointertoaclasswithmultipleinheritancethatiscasttooneoftheparents:itcanenduppointingtothesubobjectrepresentationinthemiddleoftheallocation.您可以用-no_midchunk_inheritance_ok選項將這類“錯誤”報告為”possibleleak”。還有一種可能:std::string類把一個char[]數(shù)組放置在分配空間中,并返回一個指針直接指向它,造成了一個mid-allocation指針。您可以用-no_midchunk_string_ok選項讓這類錯誤顯示為”possibleleak”。一些有用的選項:現(xiàn)實世界中真正的程序有很多不同于本文中所羅列的那些例子程序,現(xiàn)實程序更復(fù)雜,查找錯誤并不像例子所示的那么容易。DrMemory設(shè)計了一些輔助選項,靈活使用它們才能在真正的工作中得到有用的信息。監(jiān)控子程序缺省情況下DrMemory將監(jiān)控當(dāng)前進程產(chǎn)生的子進程的內(nèi)存錯誤。如果您想禁止檢查子進程,可以使用-no_follow_children選項。合并檢查結(jié)果用-aggregate選項可以合并DrMemory的檢查結(jié)果,比如下面的命令把logs目錄下面多個DrMemory報告合并為一個總的報告。這個功能在某些情況下比較有用。比如對同一個程序用多個不同的測試用例測出不同的內(nèi)存錯誤,可以把多個報告合并起來,以便程序員一次閱讀。檢查不退出程序一些程序永遠或者長時間都不退出,對于某些內(nèi)存錯誤,比如未初始化讀寫,或者非法讀寫,DrMemory一旦發(fā)現(xiàn)就立即寫入result文件。但DrMemory只有在進程退出時才檢查內(nèi)存泄露。因此對于長期運行的程序,如果我們想在其運行期間得到內(nèi)存泄露的報告,就需要使用DrMemory的nudge命令。比如您的進程pid為1000,正在被DrMemory檢測。那么你可以在Shell中運行下面這條命令,強制DrMemory進行內(nèi)存泄露檢查,并把結(jié)果更新到result文件中?,F(xiàn)在打開result文件,如果程序有內(nèi)存泄露,您將在該文件中找到錯誤信息。SuppressingErrors內(nèi)存錯誤檢查工具的一個重要能力就是能夠suppresserrors,即隱藏指定”錯誤”的能力。因為人們使用內(nèi)存錯誤檢測工具最希望的是它能給出“真正的”錯誤,而不是給出大量的不是錯誤的錯誤。工具本身可以根據(jù)一些經(jīng)驗算法隱藏一些“眾所周知”的假錯誤。但更多的情況下,需要使用者告訴工具如何區(qū)分出假錯誤。每次運行DrMemory時,它會產(chǎn)生一個suppress文件,和result文件放在一起。該文件的格式如下:圖5.suppress文件格式suppress文件有多個”O(jiān)neError”小節(jié)組成,每個”O(jiān)neError”表示一個可以被suppress的錯誤。用調(diào)用堆棧來表示,有兩種格式來表示堆棧:DrMemory支持通配符,比如t!*表示不報告所有模塊t中的錯誤。在Linux下面,模塊t,就是由t.c生成的t.o所包含的代碼,換句話說就是不檢查t.c中的錯誤。一些有用的選項:現(xiàn)實世界中真正的程序有很多不同于本文中所羅列的那些例子程序,現(xiàn)實程序更復(fù)雜,查找錯誤并不像例子所示的那么容易。DrMemory設(shè)計了一些輔助選項,靈活使用它們才能在真正的工作中得到有用的信息。監(jiān)控子程序缺省情況下DrMemory將監(jiān)控當(dāng)前進程產(chǎn)生的子進程的內(nèi)存錯誤。如果您想禁止檢查子進程,可以使用-no_follow_children選項。合并檢查結(jié)果用-aggregate選項可以合并DrMemory的檢查結(jié)果,比如下面的命令把logs目錄下面多個DrMemory報告合并為一個總的報告。這個功能在某些情況下比較有用。比如對同一個程序用多個不同的測試用例測出不同的內(nèi)存錯誤,可以把多個報告合并起來,以便程序員一次閱讀。檢查不退出程序一些程序永遠或者長時間都不退出,對于某些內(nèi)存錯誤,比如未初始化讀寫,或者非法讀寫,DrMemory一旦發(fā)現(xiàn)就立即寫入result文件。但DrMemory只有在進程退出時才檢查內(nèi)存泄露

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論