DEBUG和RELEASE版本差異及調試相關問題

來源:互聯網
上載者:User
I. 記憶體配置問題

1. 變數未初始化。下面的程式在debug中啟動並執行很好。

thing * search(thing * something)
BOOL found;
for(int i = 0; i < whatever.GetSize(); i++)
{
if(whatever[i]->field == something->field)
{ /* found it */
found = TRUE;
break;
} /* found it */
}
if(found)
return whatever[i];
else
return NULL;
而在release中卻不行,因為debug中會自動給變數初始化found=FALSE,而在release版中則不會。所以儘可能的給變數、類或結構初始化。

2. 資料溢出的問題

如:char buffer[10];
int counter;

lstrcpy(buffer, "abcdefghik");

在debug版中buffer的NULL覆蓋了counter的高位,但是除非counter>16M,什麼問題也沒有。但是在release版中,counter可能被放在寄存器中,這樣NULL就覆蓋了buffer下面的空間,可能就是函數的返回地址,這將導致ACCESS ERROR。

3. DEBUG版和RELEASE版的記憶體配置方式是不同的 。如果你在DEBUG版中申請 ele 為 6*sizeof(DWORD)=24bytes,實際上分配給你的是32bytes(debug版以32bytes為單位分配), 而在release版,分配給你的就是24bytes(release版以8bytes為單位),所以在debug版中如果你寫ele[6],可能不會有什麼問題,而在release版中,就有ACCESS VIOLATE。

II. ASSERT和VERIFY

1. ASSERT在Release版本中是不會被編譯的。

ASSERT宏是這樣定義的

#ifdef _DEBUG
#define ASSERT(x) if( (x) == 0) report_assert_failure()
#else
#define ASSERT(x)
#endif
實際上複雜一些,但無關緊要。假如你在這些語句中加了程式中必須要有的代碼
比如

ASSERT(pNewObj = new CMyClass);

pNewObj->MyFunction();

這種時候Release版本中的pNewObj不會分配到空間

所以執行到下一個語句的時候程式會報該程式執行了非法操作的錯誤。這時可以用VERIFY :

#ifdef _DEBUG
#define VERIFY(x) if( (x) == 0) report_assert_failure()
#else
#define VERIFY(x) (x)
#endif
這樣的話,代碼在release版中就可以執行了。

III. 參數問題:

自訂訊息的處理函數,必須定義如下:

afx_msg LRESULT OnMyMessage(WPARAM, LPARAM);

傳回值必須是HRESULT型,否則Debug會過,而Release出錯

IV. 記憶體配置

保證資料建立和清除的統一性:如果一個DLL提供一個能夠建立資料的函數,那麼這個DLL同時應該提供一個函數銷毀這些資料。資料的建立和清除應該在同一個層次上。

V. DLL的災難

人們將不同版本DLL混合造成的不一致性形象的稱為 “動態串連庫的地獄“(DLL Hell) ,甚至微軟自己也這麼說http://msdn.microsoft.com/library/techart/dlldanger1.htm)。

如果你的程式使用你自己的DLL時請注意:

1. 不能將debug和release版的DLL混合在一起使用。debug都是debug版,release版都是release版。

解決辦法是將debug和release的程式分別放在主程式的debug和release目錄下

2. 千萬不要以為靜態串連庫會解決問題,那隻會使情況更糟糕。

VI. RELEASE板中的調試 :

1. 將ASSERT() 改為 VERIFY() 。找出定義在"#ifdef _DEBUG"中的代碼,如果在RELEASE版本中需要這些代碼請將他們移到定義外。尋找TRACE(...)中代碼,因為這些代碼在RELEASE中也不被編譯。 請認真檢查那些在RELEASE中需要的代碼是否並沒有被便宜。

2. 變數的初始化所帶來的不同,在不同的系統,或是在DEBUG/RELEASE版本間都存在這樣的差異,所以請對變數進行初始化。

3. 是否在編譯時間已經有了警告?請將警告層級設定為3或4,然後保證在編譯時間沒有警告出現.

VII. 將Project Settings" 中 "C++/C " 項目下最佳化選項改為Disbale(Debug)。編譯器的最佳化可能導致許多意想不到的錯誤,請參http://www.pgh.net/~newcomer/debug_release.htm

1. 此外對RELEASE版本的軟體也可以進行調試,請做如下改動:

在"Project Settings" 中 "C++/C " 項目下設定 "category" 為 "General" 並且將"Debug Info"設定為 "Program Database"。

在"Link"項目下選中"Generate Debug Info"檢查框。

"Rebuild All"

如此做法會產生的一些限制:

無法獲得在MFC DLL中的變數的值。

必須對該軟體所使用的所有DLL工程都進行改動。

另:

MS BUG:MS的一份技術文檔中表明,在VC5中對於DLL的"Maximize Speed"最佳化選項並未被完全支援,因此這將會引起記憶體錯誤並導致程式崩潰。

2. http://www.sysinternals.com/有一個程式DebugView,用來捕捉OutputDebugString的輸出,運行起來後(估計是自設為system debugger)就可以觀看所有程式的OutputDebugString的輸出。此後,你可以脫離VC來運行你的程式並觀看調試資訊。

3. 有一個叫Gimpel Lint的靜態代碼檢查工具,據說比較好用http://www.gimpel.com/ 不過要化$的。

參考文獻:

1) http://www.cygnus-software.com/papers/release_debugging.html

2) http://www.pgh.net/~newcomer/debug_release.htm

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.