借花献佛==DEBUG和RELEASE 版本差异及调试相关问题
常有人问DEBUG和RELEASE的区别以及RELEASE版难以调试。找到一篇总结文章。稍作修改。大家学习。
有不正确的地方大家补充。
DEBUG和RELEASE 版本差异及调试相关问题- -
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出错、同时,WPARAM,LPARAM这两个参数一定要申明,否则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. 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
问题点数:24、回复次数:17Top
1 楼happyparrot(快乐鹦鹉)回复于 2005-09-01 16:33:14 得分 0
给出信息来源:http://cnboy.blogchina.com/1107372.htmlTop
2 楼i_noname(晚九朝五)回复于 2005-09-01 16:37:27 得分 3
好帖!
收藏Top
3 楼bobob(静思)回复于 2005-09-01 16:42:48 得分 3
顶~怎么才24啊!不厚道Top
4 楼vcmute(BCare4 H1Rest Good9!)回复于 2005-09-01 16:46:26 得分 3
种子FAQ 嘿嘿Top
5 楼lixiaosan(小三)回复于 2005-09-01 19:18:54 得分 3
鸟人,给的分还有整有零的~~`Top
6 楼hundlom(托克维尔)回复于 2005-09-01 20:11:45 得分 2
收藏!!!!Top
7 楼huxzjqhh(黑石)回复于 2005-09-02 13:54:45 得分 0
markTop
8 楼fisker0303(天塌了,地陷了,小花狗不见了.)回复于 2005-09-02 14:26:47 得分 2
不错,不错。Top
9 楼cqgaoke(技高软件公司)回复于 2005-09-02 14:34:03 得分 0
upTop
10 楼laogong165(歪锅配翘盖,好锅头有好锅盖!)回复于 2005-09-05 13:04:37 得分 2
给我点分吧
我快穷死了 :(Top
11 楼teli_eurydice(哭泣的仙人掌。。。。)回复于 2005-09-05 14:06:24 得分 2
接分Top
12 楼krfstudio()回复于 2005-09-05 14:43:00 得分 2
好帖,收藏。Top
13 楼ishallwin()回复于 2005-09-05 17:22:18 得分 0
markTop
14 楼phoenix96_2000(Arcrest)回复于 2005-09-05 19:11:22 得分 2
mark先.
优化会可能造成问题,而DEBUG默认是关闭了的,
偶遇到过两次debug好好的,release却运行结果不正确的情况,
release默认加了速度优化,而恰好就是关闭maximize speed优化(或者改为minimize size)后,release就正常,搞得很郁闷.
Top
15 楼wuchi(风云)回复于 2005-09-21 17:41:22 得分 0
markTop
16 楼echoxue(咱当过兵的人)回复于 2005-09-22 18:40:50 得分 0
upTop
17 楼softrain(曾经的月光,现在的日光)回复于 2006-02-17 10:18:45 得分 0
收藏Top
相关问题
- 哪位可以详细的介绍一下Debug调试和Release调试有什么不同?
- debug调试小问题
- Debug调试通过 Release运行出错,请高手指教,分不够再加
- 我的程序只有Release呢?怎样才能添加Debug调试环境?
- 求助:Debug调试通过但Release却出错,有可能是什么原因?
- CRichEditCtrl的Debug版本和Release版本的排版差异?
- 有一个函数在Debug环境下调试不能通过,在Release环境下却能正常调试通过。这是为什么,请执教!
- 调试问题,为什麽程序在debug 版下运行正常, 但release 版运行不正常
- 请问怎么把vc 中的调试版(debug)换成发布版(release),一个菜鸟!
- 为什么在Debug中调试通过的程序,在Release中,却有警告,而且无法运行?




