- 生成的代码
- Debug 版:生成的exe中包含有符号表等信息,因此可以进行调试/跟踪。 Release版:default状态下不包括这些信息。
- 指令Code
系统OS组件都是Release的
运行库本身分Debug和Release
- 编译Debug版包含的就是Debug版的运行库
- Debug
- 运行库中包括一些断言
- 额外的检查
断言的错误只会在debug版下发生,比如Debug模式中出现最多的Assert和Verify断言:在Debug模式下,两个宏的功 能是一样的;在Release模式下,Assert不会对参数里的表达式进行计算,相当于空语句,Verify会计算里面的表达式,如果是函数,将会调用 该函数。部分定义如下:
#ifdef _DEBUG
#define VERIFY(f) ASSERT(f)
#else
#define ASSERT(f) ((void)0)
#define VERIFY(f) ((void)(f))
假如你的Assert语句中加了程序中必须要有的代码,就应该使用Verify,这样的话,代码在Release版中就可以执行了,Debug模式下求值+断言,Release模式下只求值,不断言。
- 内存的处理
- 栈的检查
栈带有Stack Frame
在Debug版,初始化stack区前后会加一些保护的缓冲区,防止越界访问,所以在Debug模式中申请内存时,会得到比申请的还要大的空间,而Release模式则不会,申请多大得到的就是多大。
未初始化的缓冲区都是CC,CC就是中断3的机器码
在栈单元的最后有一个四字节的返回地址。所以当下溢出后,函数在返回的时候肯定会出错。所以调试程序时如果返回地址跳到了一个无效的地址上,第一个要怀疑的就是下溢出了。
在Debug版时会有一个Check Stack的动作,检查两端保护区有没有被用户程序填充。但是如果用户程序跳过了这两段保护区,就检查不出来了
- 堆的检查
在Debug版下,New会被重新定义成Debug New
Debug New是对New做了一个封装,在Debug模式下,vc的实现是使用了一个双向链表,在每一个节点的结构中会调用New的内容,比如文件名和行号等,而 对于Release版本,就没有内存链了。这样对于new和delete的调用将会被直接转到malloc.c和free.c。因为没有内存链,没有多余 的保护数据填充,没有内存越界检测机制,所以有些时候Debug版本会崩溃,但是Release版本却没有。这并不代表代码没有问题,而是内存非法访问更 难发现了,当Release版本崩溃的时候,问题也更难定位了。
常见 的堆的错误如果是Heap CORRUPT,就要检查是不是动态内存用的时候不小心写越界了
- 栈的检查
- 有一些东西是代码和内容的处理结合在一起用的
- 为什么测性能的时候不能用Debug版
- Debug的信息要付出性能上的代价,调试版本包含了调试信息,并采用了一些保护机制以帮助发现错误,因此性能不如发布版本。
- 变量初始化
-
Debug模式下会自动给变量初始化,初始化为0,而Release模式下不会,它会随机赋初值, 如果你的程序中的某个变量没被初始化就被引用,就很有可能出现异常。(不适用于.net平台)
-
Release 和 Debug的区别
最新推荐文章于 2024-02-27 14:12:49 发布
首先再次强调我们做测试时使用的二进制必须是保证所有Test Case 在 Release 版通过。Release 和 Debug版的区别,具体分析如下……