調試Release版本應用程式

來源:互聯網
上載者:User
引言
如果在您的開發過程中遇到了常見的錯誤,或許您的Release版本不能正常運行而Debug版本運行無誤,那麼我推薦您閱讀本文:因為並非如您想象的那樣,Release版本可以保證您的應用程式可以象Debug版本一樣運行。

如果您在開發階段完成之後或者在開發進行一段時間之內從來沒有進行過Release版本測試,然而當您測試的時候卻發現問題,那麼請看我們的調試規則1:

規則1: 經常性對開發軟體進行Debug和Release版本的常規測試.

測試Release版本的時間間隔越長,排除問題的難度越大,至少對Release版本進行每周1次的測試,可以使您在緊湊的開發週期內節省潛在的排故時間.

不要隨意刪除Release版本需要的代碼
這點看起來似乎再明顯不過,但卻是開發人員無意中經常犯的錯誤,原因在於編譯器編譯Release版本時候會主動排除在代碼中存在的宏,例如ASSERT和TRACE在Release版本會自動排除,這樣導致的問題是您在這些宏當中啟動並執行代碼也被隨之刪除,這是非常危險的事情J,例如:

      ASSERT(m_ImageList.Create(MAKEINTRESOURCE(IDB_IMAGES), 16, 1, RGB(255,255,255)));

這樣的代碼在Debug模式不會出錯,映像列表也自動建立了,然而在Release版本呢?後繼使用m_ImageList對象只會造成程式的Crash!,因此ASSERT宏中盡量使用邏輯運算子作為驗證。

規則 2: 不要將代碼放置在僅在某種編譯選項中執行的地方,對於使用_DEBUG等編譯選項宏內部的代碼必須不影響整個程式的使用.

規則 3: 不要使用規則2作為評判標準來刪除ASSERT宏,ASSERT宏是個有用的工具,但容易使用錯誤.

使Debug編譯模式接近Release模式
如果您的Release版本存在的問題是由代碼被編譯器自動排除造成的,那麼通過這個方法您的問題可能會重現.

一些問題的產生可能是由於不同編譯選項之間預定義符號造成的,因此您可以更改編譯模式下的預定義符號,從而使您的Debug模式接近Release模式,觀察錯誤是否產生,更改編譯預定義符號方法如下:

Alt-F7開啟項目設定,在C++/C 頁面,選擇"General"類別,更改"_DEBUG"符號為"NDEBUG".
在C++/C 頁面, 選擇"Preprocessor"類別,添加預定義符號"_DEBUG"到"Undefined Symbols"欄.
使用"Rebuild All"重新編譯
如果通過上面設定,您在Release編譯模式下面的問題在Debug模式下重現,那麼請您依據以下步驟對您的代碼進行修改:

尋找ASSERT排除其中的所有重要執行語句,或者將ASSERT修改為VERIFY.
檢查"#ifdef _DEBUG" 內所有代碼,排除Release模式使用的代碼.
尋找TRACE 排除其中的所有重要執行語句. TRACE和ASSERT一樣,僅在Debug模式下編譯.
如果通過上面修改更正了您在Debug模式下的問題,那麼您可以重新編譯Release模式,非常有可能您可以解決先前存在的問題!.

錯誤的假定造成編譯模式錯誤
您是否經常性的假定您的變數或者對象被初試化成某個指定的值(可能0)?您是否假定你所有關聯到的資源在應用程式中都存在?這些也是Debug和Release模式下不同問題產生的原因.

規則 4: 除非您在代碼中對變數進行初始化,否則不能作出如上假定. 包括全域變數,自動變數,申請對象和new對象.

這種情況還常常發生在記憶體順序的問題,記得原來使用結構體的時候為了使用方便,比較兩個結構體對象使用memcmp,在Debug版本工作正常,而Release版本計算出錯誤的解,看來的確不能進行錯誤的假定!

規則 5: 確保刪除資源的所有引用都被刪除,例如resource.h中的定義.

軟體開發中,不同編譯版本對變數和記憶體的初始化是不同的. 如果您假定變數初始化為0,那麼在Win9x系統的Release模式下,會出現異常現象。因此對所有變數,記憶體顯式清0是較為安全的做法.

如果您引用了已經被刪除的資源,您的Debug版本可以正常工作,但是Release版本可能會crash.

您是否相信編譯器?
編譯器警告層級和編譯噪音有著相當大的關係.

通過提高編譯器警告層級可增加程式隱藏問題暴露的機會.通常設定警告層級在"Level 3"或者 "Level 4".編譯並解決所有警告,這是發布Release版本應用程式的一個很好的建議.這能暴露會使您的應用程式出現問題的很多初始化問題和其它潛在的錯誤.

規則 6: 開始項目之前先將編譯警告層級設定在"Level 3" 或者 "Level 4" ,登記代碼之前確保消滅所有警告!.

總結報告
編譯模式下的調試
曾經不止一次的聽到一些VC開發人員說Release模式下面不能進行調試,幸運的是:通過相應設定,可以在Release模式進行調試,因此那隻不過是一個以訛傳訛的荒謬說法而已.

規則 7: 當前面所有的方法都無效的時候,在Release模式下面進行調試.

Release模式可以進行調試,第一步是開啟符號表:

Alt-F7開啟項目設定,在C++/C 頁面,選擇"General"類,修改Debug Info setting 為 "Program Database".
在"Link" 頁面,選擇"Generate Debug Info".
"Rebuild All"
這些設定將允許您在Release模式下保留符號表,您也可以同時考慮以下設定:

調試Release版本應用程式,您可以關閉最佳化選項.
如果在Release模式下面不能設定斷點,添加指令"__asm {int 3}" 可以是您的應用程式在改行停止(確定在發布應用程式時候排除這些代碼).
在Release模式進行調試的幾個限制.

最大的問題在於您不能跟蹤到MFC函數內部,原因在於Release版本的MFC動態連結程式庫不包含調試資訊和符號表.
同上,想要調試調用的dll,您必須給它們全部加上調試資訊和符號表.
編譯器產生了錯誤的代碼?
或許有的時候您會發現VC++編譯器產生了’問題代碼’,然而坦率的講,人們通常抱怨的太早.您可以在Release模式下面關閉最佳化選項來進行測試.

如果這個操作解決了您的問題,或許您的編碼習慣存在問題. 信不信由你, 極其可能在您的編碼中存在模稜兩可的求解或者看起來似乎正確,某些條件下也是正確的情況. 舉個例子,下面的代碼在Debug模式似乎一切’正常’,而在Release模式下面卻會出錯!

#include <stdio.h>

int* func1()
{
int retval = 5;
return &retval;
}

int main(int argc, char* argv[])
{
printf("%d\n", *func1());
return 0;
}
我相信大多數程式員尤其是初學者容易遇到此類情況的.

規則 8: 如果關閉Release模式的最佳化選項可以使您的應用程式運行正常,而開啟最佳化選項則出現問題的化,原因多半在於您的不良編碼習慣造成的. 這意味著必須仔細檢查您的代碼,清理出那些錯誤的假設,懸null 指標等等. 等同的這告訴您,在Debug模式和關閉最佳化選項的Release模式下您的應用程式工作正常全是因為系統隱含的運氣,您必須著手更正存在隱患的代碼,否則在日後可能會造成巨大的損失.

規則 9: 如果您已經徹底檢查了您的代碼,並且沒有發現問題,那麼您最好逐個開啟最佳化選項將產生錯誤的原因限制在某個範圍之內.

BTW- 以上問題代碼由C++編譯器自動檢出. 如果您已經遵循 規則 6 您或許在前面環節中已經解決了這些問題.

憑我的開發經驗,編譯器極少會產生錯誤的代碼(當然要注意介面程式邊界對齊的問題).通常在使用模板類時候VC6編譯器或許會產生斷言ASSERT錯誤,這種情況您只需更新補丁即可解決.

最後的思考
在日常編碼中只需稍微增加一點嚴格的檢測,便能有效避免新的Debug -v- Release模式問題的產生,以下是我的一些經驗.

1.      取出(check out)需要修改的代碼.

2.      修改代碼,排除所有警告,編譯Debug和Release版本.

3.      詳細測試新代碼,即單步調試新程式碼片段之後進入工作代碼,確保代碼無誤.

4.      更正所有問題.

5.      確認無誤之後將新代碼登記入庫(check in).

6.      對登記入庫的代碼進行全新的編譯,確保新登記代碼與其它代碼融合.

7.      重新詳細測試代碼.

8.      更正新問題(或許可以發現登記入庫代碼存在的問題)

嚴格按照以上步驟,您在設計開發過程中即可解決大量問題,避免在最後發布應用程式時候產生新的難以定位的問題.

原文來自於codeproject,

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.