【转】程序debug正常release错误
生活随笔
收集整理的這篇文章主要介紹了
【转】程序debug正常release错误
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
原文:http://hi.baidu.com/leggle/blog/item/ec0c2e5400c3ed5dd10906a7.html
呵呵,Iris來了!由于最近所做項目接近尾聲,想在release下運行卻發(fā)現(xiàn)遇此問題,遂在網(wǎng)上搜尋,摘錄如下:
VC編寫程序在debug下正常,在release下錯誤可能存在的原因:
1、內(nèi)存分配問題
(1)變量初始化
Release對程序的要求較Debug嚴(yán)格,應(yīng)該對所有的變量(特別是指針和BOOL型)都先初始化再使用。
(2)數(shù)據(jù)溢出的問題
如:程序段 char buffer[4]; int num; strcpy(buffer,”abcd”);
在debug 版中buffer的NULL覆蓋了num的高位,但是除非num >16M,什么問題也沒有。但是在release版中, num可能被放在寄存器中,這樣NULL就覆蓋了buffer下面的空間,可能就是函數(shù)的返回地址,這將導(dǎo)致ACCESS ERROR。
(3)內(nèi)存分配方式不同
如果你在DEBUG版中申請 ele 為 6*sizeof(DWORD)=24bytes,實際上分配給你的是32bytes(debug版以32bytes為單位分配),而在release版,分配給你的就是24bytes(release版以8bytes為單位),所以在debug版中如果你寫ele[6],可能不會有什么問題,而在release版中,就有ACCESS VIOLATE
2、用戶自定義消息應(yīng)該按照定義的方式去使用
對于用戶自定義消息: #define WM_USERMESSAGENAME WM_USER+1
ON_MESSAGE定義: ON_MESSAGE(WM_USERMESSAGENAME, OnUserMessageName), 該宏需要兩個參數(shù),如果消息響應(yīng)函數(shù)并沒有參數(shù),編譯器在壓棧出棧時就會出錯,而DEBUG版運行時編譯器會自動加一些測試代碼,所以不會造成堆棧的破壞。
解決辦法:1)把ON_MESSAGE 替換成ON_MESSAGE_VOID (頭文件<AFXPRIV.H>),該宏不需要參數(shù)
2)修改消息響應(yīng)函數(shù): afx_msg void OnUserMessageName(WPARAM wparam, LPARAM lparam) //一定要加參數(shù),不管用不用得到
3、ASSERT和VERIFY
ASSERT在release版本中不會被編譯,若在ASSERT中有空間分配等,就會帶來錯誤。改為VERIFY即可。
4、內(nèi)存分配
保證數(shù)據(jù)創(chuàng)建和清除的統(tǒng)一性:如果一個DLL提供一個能夠創(chuàng)建數(shù)據(jù)的函數(shù),那么這個DLL同時應(yīng)該提供一個函數(shù)銷毀這些數(shù)據(jù)。數(shù)據(jù)的創(chuàng)建和清除應(yīng)該在同一個層次上。
5、DLL的災(zāi)難
如果你的程序使用你自己的DLL時請注意:
1)不能將debug和release版的DLL混合在一起使用。debug都是debug版,release版都是release版。
2)千萬不要以為靜態(tài)連接庫會解決問題,那只會使情況更糟糕。
6、將Project Settings中 C++/C 項目下優(yōu)化選項改為 Disable(Debug)
編譯器的優(yōu)化可能導(dǎo)致許多意想不到的錯誤。
參考:http://www.cygnus-software.com/papers/release_debugging.html
另附zz:
(1) 幀指針(Frame Pointer)省略(簡稱 FPO ):在函數(shù)調(diào)用過程中,所有調(diào)用信息(返回地址、參數(shù))以及自動變量都是放在棧中的。若函數(shù)的聲明與實現(xiàn)不同(參數(shù)、返回值、調(diào)用方式),就會產(chǎn)生錯誤 ————但 Debug 方式下,棧的訪問通過 EBP 寄存器保存的地址實現(xiàn),如果沒有發(fā)生數(shù)組越界之類的錯誤(或是越界“不多”),函數(shù)通常能正常執(zhí)行;Release 方式下,優(yōu)化會省略 EBP 棧基址指針,這樣通過一個全局指針訪問棧就會造成返回地址錯誤是程序崩潰。C++ 的強類型特性能檢查出大多數(shù)這樣的錯誤,但如果用了強制類型轉(zhuǎn)換,就不行了。你可以在 Release 版本中強制加入 /Oy- 編譯選項來關(guān)掉幀指針省略,以確定是否此類錯誤。
(2) volatile 型變量:volatile 告訴編譯器該變量可能被程序之外的未知方式修改(如系統(tǒng)、其他進(jìn)程和線程)。優(yōu)化程序為了使程序性能提高,常把一些變量放在寄存器中(類似于 register 關(guān)鍵字),而其他進(jìn)程只能對該變量所在的內(nèi)存進(jìn)行修改,而寄存器中的值沒變。如果你的程序是多線程的,或者你發(fā)現(xiàn)某個變量的值與預(yù)期的不符而你確信已正確 的設(shè)置了,則很可能遇到這樣的問題。這種錯誤有時會表現(xiàn)為程序在最快優(yōu)化出錯而最小優(yōu)化正常。把你認(rèn)為可疑的變量加上 volatile 試試。
總結(jié)
以上是生活随笔為你收集整理的【转】程序debug正常release错误的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ES6 扩展运算符
- 下一篇: android js 代码混淆工具,好用