調試
Release
版本應用程序
引言
如果在您的開發過程中遇到了常見的錯誤,或許您的
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
模式,觀察錯誤是否產生,更改編譯預定義符號方法如下
:
打開項目設置,在
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
模式的優化選項可以使您的應用程序運行正常,而打開優化選項則出現問題的化,原因多半在于您的不良編碼習慣造成的
.
這意味著必須仔細檢查您的代碼,清理出那些錯誤的假設,懸空指針等等
.
等同的這告訴您,在
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版本應用程序發布,產生錯誤的時候苦苦求索得到的一些經驗,原文來自于codeproject,經過本人潤色,改寫成為適合國內開發者的文章,希望能對大家有用,謝謝!
posted on 2007-03-09 11:53
飛鳥 閱讀(481)
評論(0) 編輯 收藏 所屬分類:
VC