MFC調試工具——之BoundsChecker用法

BoundsChecker 是一個Run-Time錯誤檢測工具,它主要定位程序在運行時期發生的各種錯誤。BoundsChecker能檢測的錯誤包括:

1、指針操作和內存、資源泄露錯誤,比如:

內存泄露;

資源泄露;

   對指針變量的錯誤操作。

2、內存操作方面的錯誤,比如:

   內存讀、寫溢出;

   使用未初始化的內存。

3、API函數使用錯誤 

BoundsChecker安裝成功後,在你的VC++集成開發環境中,會多出了一個名爲BoundsChecker的菜單,如下所示:


BoundsChecker 已經非常完好的集成到VC++集成開發環境中了。

使用BoundsChecker對程序的運行時錯誤進行檢測,有兩種使用模式可供選擇。一種模式叫做ActiveCheck,一種模式叫做FinalCheck。下面分別進行介紹。


1.1 ActiveCheck
ActiveCheck是BoundsChecker提供的一種方便、快捷的錯誤檢測模式,它能檢測的錯誤種類有限,只包括:內存泄露錯誤、資源泄露錯誤、API函數使用錯誤。

要想使用ActiveCheck模式來檢測程序的運行時錯誤,只需在VC++集成開發環境中打開BoundsChecker功能,然後從調試狀態運行程序即可。此時ActiveCheck會在後臺自動運行,隨時檢測程序是否發生了錯誤。下面說一下具體的使用步驟。

1.1.1 用ActiveCheck來檢測錯誤
使用ActiveCheck的具體的操作步驟如下:

首先,在VC++集成開發環境中打開你要對其進行測試的程序,同時保證項目處於Debug編譯狀態下。

其次,確保VC++集成開發環境中[BoundsChecker/Integrated Debugging]菜單項和[BoundsChecker/Report Errors and Events]菜單項處於被選中的狀態。只有這兩項被選中,BoundsChecker纔會在程序運行過程中發揮作用。

最後,在VC++集成開發環境中選擇[Build/ Start Debug/Go]菜單命令,在Debug狀態下運行程序,ActiveCheck也在後臺開始運行了。

這時,就可以按照制定好的測試用例,對程序進行操作。凡是程序執行過的代碼,如果存在錯誤,ActiveCheck就會記錄下來。

有一個地方要說一下,在[BoundsChecker]菜單中有一項[Report Errors Immediately],如下圖所示:


該菜單項對於ActiveCheck 模式,以及下面就要介紹的FinalCheck模式的作用是一樣的,即:如果不選中該項,則BoundsChecker會記錄程序運行過程中發現的各種錯誤,直到程序結束後再進行報告;當選中該菜單項時,在程序的運行過程中,一旦BoundsChecker發現錯誤,會馬上彈出如下的對話框進行提示:


下面按圖中標註的數字序號解釋一下對話框中各個按鈕的功能:

按鈕1:點擊該按鈕,則表示先暫時不理會這個錯誤,繼續執行程序。 

按鈕2:點擊該按鈕,則會馬上跳轉到出現問題的代碼行處。處理完問題後,點擊[Build/ Start Debug/Go]菜單項,可以繼續執行程序,進行檢測。

按鈕3:點擊該按鈕,則將該錯誤添加到被忽略的錯誤列表中去,當再次出現這個問題時,BoundsChecker將不會進行報告。

按鈕4:點擊該按鈕,則立即終止程序的執行。

按鈕5:點擊該按鈕,會顯示當前內存的申請、使用情況。

按鈕6:點擊該按鈕,會得到當前這個錯誤的幫助信息。 

按鈕7、8: 這兩個按鈕與[BoundsCheckerReport Errors Immediately]和[BoundsChecker Report Errors and Event] 菜單命令的功能是完全一樣的,在此不再贅述。

按鈕9:點擊該按鈕,會顯示/隱藏與該錯誤有關的函數調用堆棧情況,以及具體的出錯代碼行的位置。

是否選中[BoundsChecker/Report Errors Immediately]菜單項,完全取決於你自己的喜好,以及測試時的具體情況。如果你想要BoundsChecker在程序運行過程中實時向你彙報發現的錯誤,那麼你就選中這個菜單項;如果想等到操作結束後,再對操作過程中BoundsChecker發現的錯誤統一進行分析,就不必選中這個菜單項。我在平常使用過程中更偏向於使用後一種。

1.1.2 分析錯誤
在你操作全部結束,退出程序後,

BoundsChecker 會顯示一個所發現錯誤的列表。我們需要對列表中羅列的錯誤進行分析,來確定錯誤的原因和位置。

在錯誤檢測結果列表中,羅列出了在程序的執行過程中ActiveCheck檢測到的所有的內存泄露、資源泄露和API函數使用錯誤的相關信息。如下圖所示:


在左邊的窗口中,逐條列出了程序在內存、資源、API 函數使用上的問題,包括:該問題的種類,該問題發生的次數,如果是內存泄露,損失了多少內存,以及發生該問題的代碼位置等等。當你用鼠標單擊選中某一條記錄時,在右邊的窗口中會顯示出與該條錯誤記錄相對應的函數調用堆棧情況。當你用鼠標雙擊某一條錯誤記錄時,會定位到引發該錯誤的源代碼處。
好了,BoundsChecker在ActiveCheck模式下的使用方法至此介紹完了,是不是很簡單?
在ActiveCheck模式下檢測程序時,程序的運行速度基本不受影響,但其缺點是檢測的錯誤種類有限,即只能檢查出內存泄露錯誤、資源泄露錯誤、API函數使用錯誤。BoundsChecker 提供了另外一種檢測錯誤的模式—— FinalCheck,也就是我們在前面提到的BoundsChecker的第二種使用模式。 FinalCheck可以檢測出程序中更多的錯誤。下面我們就對它進行介紹。

1.2 用 FinalCheck檢測更多的錯誤 
FinalCheck具有BoundsChecker提供的所有檢錯功能。FinalCheck 是ActiveCheck的超集,它除了能夠檢測出ActiveCheck能夠檢測出的錯誤,還能發現很多 ActiveCheck 不能檢測到的錯誤,包括:指針操作錯誤、內存操作溢出、使用未初始化的內存等等,並且,對於ActiveCheck能檢測出的錯誤,FinalCheck能夠給出關於錯誤更詳細的信息。所以,我們可以把FinalCheck認爲是ActiveCheck的功能增強版。我們付出的代價是:程序的運行速度會變慢,有時甚至會變的很慢。

要想在FinalCheck 模式下測試程序,不能使用VC++集成開發環境提供的編譯連接器來構造程序,而必須要使用BoundsChecker提供的編譯連接器來編譯連接程序。當 BoundsChecker的編譯連接器編譯連接程序時,會向程序中插裝一些錯誤檢測代碼,這也就是FinalCheck能夠比ActiveCheck找到更多錯誤的原因。

下面就

介紹一下如何在FinalCheck模式下對程序進行測試:

1在VC++集成開發環境中打開你所要測試的項目。

2由於要使用BoundsChecker的編譯連接器重新編譯連接程序,所以我們爲BoundsChecker獨自構造一個文件夾。在VC++集成開發環境中,具體操作方法是:

A)點擊[ Build/Configurations...]菜單命令。

B)在彈出的對話框中點擊 Add 按鈕。在Configuration 編輯框中添入你爲BoundsChecker創建的文件夾的名稱,這個名稱是任意的,比如我們取名爲BoundChecker。

C)在 Copy settings from組合框中選中 XXX—Win32 Debug項,然後點擊OK按鈕,接着點擊Close按鈕。

現在,我們已經爲FinalCheck構造好了一個文件夾。

3 點擊[Build/Set Active Configuration…] 菜單命令,選中你剛纔爲BoundsChecker建的文件夾, 然後點擊OK按鈕。這樣BoundsChecker編譯連接程序時生成的中間文件、可執行程序,都會被放到該文件夾下。

4選擇[BoundsChecker/Rebuild All with BoundsChecker] 菜單命令,對程序重新進行編譯連接,也就是在這時,BoundsChecker向被測程序的代碼中加入了錯誤檢測碼。編譯連接完成後,BoundsChecker會在你爲BoundsChecker構造的文件夾中生成可執行文件。

在FinalCheck模式下對程序進行檢測的準備工作都已經做好,這時可以啓動程序開始測試了, 

操作步驟與在ActiveChecker模式下沒什麼區別。具體步驟如下:

確保VC++集成開發環境中[BoundsChecker/ Integrated Debugging]菜單項和[BoundsChecker/Report Errors and Events]菜單項處於選中狀態。 
點擊[ BuildStart Debug]菜單,選中“Go” 菜單項。程序開始在Debug狀態下運行。 
按照你制定好的測試用例,對程序進行操作。  
當BoundsChecker檢測到了錯誤時,會彈出窗口向你彙報,你可以當時就進行處理,也可以等到你的操作全部完成,退出程序之後再對列出的這些錯誤進行分析。這完全取決於你是否選中了[BoundsChecker/Report Errors Immediately] 菜單項。 
退出程序後,BoundsChecker會給出錯誤檢測結果列表。該錯誤列表與ActiveChecker給出的錯誤列表的查看方法完全一樣。只不過這個列表中所報告的信息會更多、更詳細一些。  
好了,BoundsChecker在FinalCheck模式下的使用也介紹完了。ActiveChecker、FinalCheck這兩種模式,比較而言各有長短。ActiveChecker使用方便,只需在Debug狀態下直接運行程序即可,並且程序的運行速度較快,但檢測的錯誤種類有限;FinalCheck模式下,需要使用BoundsChecker的編譯連接器重新編譯連接生成可執行程序,並且程序的運行速度比較慢,但檢測的錯誤種類、提供的錯誤相關信息要多於ActiveChecker。所以,何時使用何種模式,應根據當時的具體情況而定。

1.3 檢測Win32 API函數的兼容性
BoundsChecker還提供了一個功能——檢測程序中使用的Win32 API函數在不同平臺上的兼容性。該功能與前面提到的ActiveChecker、FinalCheck模式沒有什麼關係,它是獨立的一個功能。

雖然大多數Win32 API函數都適用於Win95、Win98、Win2000、WinNT等不同的Windows操作系統平臺,但並不是所有的API函數都滿足這種情況。你可能不知不覺的使用了在某一個平臺下允許,在另一個平臺下卻不允許使用的API函數,而項目的要求是:程序能夠在這兩種平臺下運行。 BoundsChecker提供的這個檢測Win32 API函數兼容性的功能,恰好能夠處理這個問題。

該功能的使用方法如下:

啓動[BoundsChecker/View/Compliance Report]菜單命令,如下圖所示:



在對話框中選擇程序承諾能夠運行的平臺,以及被要求遵從的其他標準(標準C和擴展的標準C),點擊“OK”按鈕,BoundChecker會給出兼容性檢測報告。

1.4 忽略錯誤
在某些情況下,我們需要忽略BoundsChecker報告的一些錯誤,這些情況包括:

1 誤報。BoundsChecker 指定程序中的某段代碼存在錯誤,但經過我們的仔細檢查,證實程序確實沒有這個錯誤,這是BoundsChecker的誤報。工具畢竟是工具,它只能依照爲它制定的算法行事,所以會有誤報的情形發生。但千萬不要輕易認定某一個錯誤爲誤報,一定要對錯誤進行仔細的分析,確定是真正的誤報。

2第三方的代碼。BoundsChecker指定的錯誤發生位置在第三方提供的代碼中,包括第三方提供的程序庫、DLL、OCX等。對於這種情況,我們也要先進行認真的檢查,確定不是由於我們錯誤的使用第三方的代碼引起的。如果最後確定不是我們的原因,則這樣的錯誤報告可以忽略。

1.5 其他
還有一點需要強調,使用BoundsChecker對程序進行測試時,需要有程序的源代碼。如果沒有源碼,BoundsChecker雖然也可以打開EXE文件將其執行起來,但得出的測試結果經常是不正確的,因此也就沒有太大的意義。

另外,除了可以在VC++集成開發環境中使用BoundChecker外,從 [開始菜單] 中啓動BoundChecker,然後打開經BoundChecker編譯連接生成的可執行文件,也可以對程序進行測試,操作方法與集成到VC++集成開發環境中的BoundChecker的操作方法是一樣的,在此就不贅述了。

至此,BoundChecker所提供的功能全部介紹完了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章