除錯Release版本應用程式

2021-06-12 14:09:17 字數 3965 閱讀 8089

目錄

(?)[+]

引言不要隨意刪除release版本需要的**

使debug編譯模式接近release模式

錯誤的假定造成編譯模式錯誤

您是否相信編譯器

總結報告

編譯模式下的除錯

編譯器生成了錯誤的**

最後的思考

後記除錯release版本應用程式引言

不要隨意刪除release版本需要的**

使debug編譯模式接近release模式

錯誤的假定造成編譯模式錯誤

您是否相信編譯器

總結報告

編譯模式下的除錯

編譯器生成了錯誤的**

最後的思考

後記除錯release版本應用程式

如果在您的開發過程中遇到了常見的錯誤,或許您的release版本不能正常執行而debug版本執行無誤,那麼我推薦您閱讀本文:因為並非如您想象的那樣,release版本可以保證您的應用程式可以象debug版本一樣執行。

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

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

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

這點看起來似乎再明顯不過,但卻是開發人員無意中經常犯的錯誤,原因在於編譯器編譯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

巨集是個有用的工具,但容易使用錯誤.

如果您的release版本存在的問題是由**被編譯器自動排除造成的,那麼通過這個方法您的問題可能會重現.

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

如果通過上面設定,您在release編譯模式下面的問題在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模式可以進行除錯,第一步是開啟符號表:

這些設定將允許您在release模式下保留符號表,您也可以同時考慮以下設定:

在release模式進行除錯的幾個限制.

或許有的時候您會發現vc++編譯器生成了』問題**』,然而坦率的講,人們通常抱怨的太早.您可以在release模式下面關閉優化選項來進行測試.

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

#include
int* func1()
int main(int argc, char* argv)
我相信大多數程式設計師尤其是初學者容易遇到此類情況的.

規則8: 如果關閉release模式的優化選項可以使您的應用程式執行正常,而開啟優化選項則出現問題的化,原因多半在於您的不良編碼習慣造成的. 這意味著必須仔細檢查您的**,清理出那些錯誤的假設,懸空指標等等. 等同的這告訴您,在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.      更正新問題(或許可以發現登記入庫**存在的問題)

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

**:

除錯Release版本應用程式

如果在您的開發過程中遇到了常見的錯誤,或許您的 release 版本不能正常執行而 debug 版本執行無誤,那麼我推薦您閱讀本文 因為並非如您想象的那樣,release 版本可以保證您的應用程式可以象 debug 版本一樣執行。如果您在開發階段完成之後或者在開發進行一段時間之內從來沒有進行過 re...

如何除錯程式的 Release 版本

首先,徹底的release版本 vc預設 是無法進行源 級別的除錯的,即使從別的地方把pdb檔案拷貝過來也沒用。如果想要進行源 級別的除錯,在生成release版本 dll,exe,ocx 時就要把一些除錯資訊build到dll exe ocx中,並讓編譯程式生成對應的pdb檔案來儲存詳細的除錯資訊...

如何除錯程式的 Release 版本

首先,徹底的release版本 vc預設 是無法進行源 級別的除錯的,即使從別的地方把pdb檔案拷貝過來也沒用。如果想要進行源 級別的除錯,在生成release版本 dll,exe,ocx 時就要把一些除錯資訊build到dll exe ocx中,並讓編譯程式生成對應的pdb檔案來儲存詳細的除錯資訊...