程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 如何在BCB中使用CodeGuard

如何在BCB中使用CodeGuard

編輯:關於C++

一、為什麼寫這篇東西

自己在使用BCB5寫一些程序時需要檢查很多東西,例如內存洩漏、資源是否有釋放等等,在使用了很多工具後,發覺BCB5本身自帶的工具--CodeGuard,非常不錯,使用也挺方便的,但是摸索了很久(以及翻查了一些資料,包括HELP)才算是會用了。寫這篇文章的目的希望有這方面的問題的朋友可以借鑒一下,大家互相學習,共同進步。我的聯系方法:Email:[email protected],希望志同道合的朋友來信互相交流。以下這篇文章算是拼湊出來的一篇文章,一些資料是在書上找的,一些是在HELP上看到了。首先聲明本人的語文及英語水平十分有限,有寫錯或者翻譯錯的地方,還望給位指出。特別感謝XX的愛情幫我校對……

二、什麼是CodeGuard

CodeGuard是在是C++Builder5才出現的一個工具。CodeGuard是C++Builder中一個程序在運行時期的檢查器,用於檢查內存或者資源的使用,以及函數調用的驗證。

CodeGuard可以檢測到以下的程序運行期錯誤:

非法的內存釋放。

無效的句柄或者文件流。

非法指針。

使用已被釋放的指針。

內存洩漏。

分配但最後沒有釋放的內存變量。

傳遞給函數的不正確的參數(包括VCL以及Win32函數)。

函數返回值的錯誤。(包括VCL以及Win32函數)。

例如:在應用程序中試圖多次釋放相同的資源(或者已經釋放了的資源)、試圖訪問已經被釋放的內存。

三、在BCB5中怎樣使用CodeGuard--配置CodeGuard

如果要使用CodeGuard的話,必須有些代碼編譯進你的應用程序,所以在改變以下這些設置後。必須全部重新編譯(切記切記!!!)。第一、打開應用程序的工程選項的CodeGuard頁框,把CodeGuard Validation前面打勾.

工程選項裡,還有其他三個選項。第一個選項允許CodeGuard檢查指向局部、全局和靜態變量的無效指針和數據溢出。第二個選項允許CodeGuard檢測對非法的(無效的、已刪除的)對象的方法的調用。第三個選項允許CodeGuard驗證內嵌指針的訪問(在某些資料上說,開啟這個選項會造成程序執行速度變得很慢,我測試過了,如果工程不是很大的話不是很明顯,可以接受。)一般的調試是開打所有的選項(默認選擇也是全部打開)。

通過CodeGuard的配置工具,可以配置CodeGuard的一些選項,在命令行方式執行CGCONFIG.EXE。可以見到一個對話框.

Preferences標簽頁用於設置CodeGuard這個工具的全局選項。Enable選項可以在應用程序不重新編譯的情況下使用或者不使用CodeGuard,一般來說是都是啟用她。如果使用CodeGuard的話,建議設置工程選項來禁止或者使用CodeGuard。Stack fill frequency填充棧頻率是檢測對運行期棧的無效訪問。Report和Error Message Box選項是設置CodeGuard報告錯誤的方式。在Report裡,Stiatistics選項打開CodeGuard輸出分配和釋放內存的統計表、被使用的Win32API的調用、資源的使用情況,並在日志文件中加上一個模塊列表,以便檢查錯誤。Resource Leaks選項是告訴CodeGuard在應用程序結束後報告資源洩漏的情況。選定了Error Message Box選項後,當應用程序不在IDE裡運行時,如果CodeGuard檢測到錯誤信息,那麼將采用一個對話框的方式告訴使用者。其他選項一般不常用,可以參見C++Builder的聯機HELP。

CodeGuard配置工具中的Resource Options和Function Options頁框允許用戶對應用程序的資源、文件和函數調用設置各種跟蹤選項。除非特殊的原因需要改變默認的配置,否則使用缺省的設定就行了。Function Options頁上有一個比較常用的選項就是記錄一個特定函數的每次調用情況。

Ignored Modules頁框允許你告訴CodeGuard,當檢測的時候可以忽略一些運行期的錯誤(一般是指某些DLL或者包)。這個選項一般不常用。

四、使用CodeGuard

使用CodeGuard其實很簡單,只要像之前那樣配置了CodeGuard,然後運行你的應用程序,無論你的應用程序是否在IDE中運行,CodeGuard都將會按照CodeGuard配置的選項監視你的應用程序。同時,他還會向一個日志文件裡輸出所有的信息(文件存放在你的工程所在目錄中,文件名和工程名一樣,擴展名為.cgl)。例如你的工程名為C:\Word\Test.prg,那麼CodeGuard的日志文件為C:\Word\Test.cgl,它是一個文本文件,可以用任何的文本編輯器來編輯它。

在IDE中,可以通過<菜單>View->Debug Window->CodeGuard Log來查看CodeGuard的日志文件(或者用快捷鍵Ctrl+Atl+O)。

如果你的程序在運行是出現屬於CodeGuard監視的錯誤的時候,CodeGuard會把它輸出到CodeGuard Log中。並將錯誤信息用一顆"樹"的方式顯示(使用很方便,就像使用Windows的資源管理器一樣簡單)。每個錯誤都可以展開,以顯示某種錯誤類型所特有的一些信息。例如:一個資源那個地方使用了、分配以及釋放;發生錯誤時的棧信息;並且指出了出錯的代碼行。這樣就可以很快的找到錯誤的根源!

CodeGuard Log窗口上有兩個按鈕Stop和Clear。當Stop選中的時候,如果這個時候程序遇到了錯誤,CodeGuard將停止應用程序。如果未選中,那麼程序就算遇到了錯誤也會繼續,這樣可以運行一次記錄很多錯誤信息。當Clear選中的時候,應用程序每次重新運行將清空日志中的信息。

在CodeGuard Log窗口中,雙擊單個錯誤的節點的時候,如果存在源代碼的話,IDE窗口會自動跳到那一行代碼上。如果不存在源代碼的話,則顯示CPU窗口。圖三中,出現的錯誤是資源洩漏。當你的鼠標雙擊Tform1:Button1Click這一行的時候,會自動跳到源代碼中出現錯誤的那一行。

當CodeGuard檢測到一個錯誤的時候,並找到出現問題的源代碼時,剩下的工作就是如果改正你的代碼。這個過程可以配合監視和數據斷點來實現,效果更加好!

五、CodeGuard中的錯誤以及原因(這一章由於個人的水平有限,難免漏、錯)

CodeGuard可以檢測到很多運行期的錯誤!通常很容易就可以從CodeGuard的含義找出錯誤的根源。對於大多數的錯誤,CodeGuard一般會顯示的包括:發生錯誤的地方、資源分配、資源釋放、資源被分配以及被訪問字節數。

1. Access In Freed Memory

如果內存被釋放了,在後面還繼續訪問,就會發生這個錯誤。在C/C++中,通常使用new或者malloc分配內存,用delete和free釋放。以下是一個訪問了被釋放的內存的例子:

void foo()
{
TMyClass *MyClass = new TMyClass();
delete MyClass;
MyClass->xxxx = 10; //MyClass已經被釋放了
}

CodeGuard會報告已被釋放的內存在何處被訪問,內存原來被分配的地方以及內存在哪裡被釋放的。

2. Method Called On Freed Object

這個錯誤跟前一個錯誤類似。起因是由於調用了已被釋放的對象的方法而不是訪問已被釋放的內存!

void foo()
{
TMyClass *MyClass = new TMyClass();
delete MyClass;
MyClass->xxxx (10);
}

CodeGuard將顯示在何處調用了已釋放對象的方法,對象被創建的地方以及對象被釋放的地方。

3. Reference To Freed Resource

在程序中試圖多次(兩次以上)釋放同一個資源,CodeGuard將檢測到這個錯誤,有好幾種方法都會產生這個錯誤!例如:

void foo()
{
TMyClass *MyClass = new TMyClass();
delete MyClass;
delete MyClass;
}

CodeGuard將報告資源在何處第二次被釋放,從而引起這個錯誤的。還會報告資源在何處分配,在何處首次釋放。

4. Method Called On Illegally Casted Object

如果在程序中對有效的內存范圍之外的方法的調用將會引起這個錯誤。

void foo()
{
TMyClass *MyClass = new TMyClass[5];
MyClass[5].xxxx(); //No such MyClass[5]
delete []MyClass;
}

CodeGuard將報告對象調用的方法定義的地方,以及這個方法被調用的地方以及對象或者內存被分配地方。

5. Resource Type Mismatch

如果在程序中釋放資源和定義(分配)時候不一致,會出現這個錯誤。

void foo()
{
TMyClass *MyClass = new TMyClass[2];
delete MyClass; //Code1
TMyClass *MyClass = new TMyClass();
delete []MyClass; //Code2
}

在Code1以及Code2都會引發Resource Type Mismatch錯誤,CodeGuard將會報告資源在何處以不一致的方式被釋放,以及資源是在哪裡被分配的地方。

6. Access Overrun

當訪問非法內存區域的內存時會造成這個錯誤(所訪問的內存在合法內存區域之後),通常情況下是數組下標引用超出原來定義的。

void foo()
{
TMyClass *MyClass = new TMyClass[2];
MyClass[2].abc = 10; //No such MyClass[2]
delete [] MyClass;
char *ch = new char[5];
strcpy(ch, "123456"); //Error
delete []ch;
}

CodeGuard報告出錯的地方,資源在哪裡分配的。

7. Access Underrun

當訪問非法內存區域的內存時會造成這個錯誤(所訪問的內存在合法內存區域之前)。

void foo()
{
TMyClass *MyClass = new TMyClass[2];
MyClass[-1].abc = 10; //No such MyClass[2]
delete [] MyClass;
}

CodeGuard報告出錯的地方,資源在哪裡分配的。

8. Uninitialized Stack Accessing

訪問棧中為被初始化的區域將會造成這個錯誤。

void foo1(int **Ptr)
{
int Var;
*Ptr = &Var;
}
void foo()
{
int *Ptr;
foo1(&Ptr);
*Ptr = 100;
}

CodeGuard將會報告何處訪問還沒有被初始化的棧。

9. Access In Invalid Stack

當在程序中嘗試訪問棧底部的內存的時候出現這個錯誤!

void foo()
{
char str[20];
strcpy(&str[-1], "szbug");
}

CodeGuard報告發生錯誤的地方。

10. Bad Parameter

這個錯誤通常是出現無效的文件或者其他資源句柄作為參數傳遞給VCL或者Win32API函數時發生的。

Void foo()
{
FILE *Stream;
fclose(Stream);
}

CodeGuard將報告使用了不正確參數的函數在何處被調用。

11. Function Failure

這個錯誤是CodeGuard在捕獲VCL以及Win32API函數的返回值如果出現錯誤時引發的。

viod foo()
{
CopyFile("abc.txt", "acbd.txt", true);
//如果這個函數由於某種原因失敗了,
//那麼CodeGuard將會捕獲並報告Function Failure錯誤!
}

12. Resource Leak

如果在程序中資源(包括Winwos資源,內存資源等等),分配了,在程序的最後沒有釋放!將引發Resource Leak錯誤。

Void foo()
{
char *ch = new char[10];
}

CodeGuard將報告資源創建的地方,以及所洩漏的字節數。

六、CodeGuard還可以檢測到應用程序的很多錯誤,這裡只說說一些常見的錯誤,其他的錯誤和例子請參見C++Builder的HELP。希望大家通過CodeGuard找出程序中的錯誤以及Bug!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved