在debugging模式下,发布版本中缺陷的常见原因不存在

错误和exception程序行为的典型原因是什么,它们仅在释放编译模式下performance出来,但在debugging模式下却不会发生?

很多时候,在C ++的debugging模式下,所有variables都是空初始化的,而除非明确说明,否则在释放模式下不会发生相同的变化。

检查任何debuggingmacros和未初始化的variables

您的程序是否使用线程,然后优化也可能会在发布模式下导致一些问题。

还要检查所有exception,例如与发布模式没有直接关系,但是有时候我们忽略了一些重要的exception,比如VC ++中的mem访问冲突,但是至less在Linux,Solaris等其他操作系统中,这可能是一个问题。 理想情况下,你的程序不应该捕获像访问一个NULL指针这样的重要exception。

一个常见的陷阱是在ASSERT中使用带有副作用的expression式。

其他差异可能是:

  • 在垃圾收集语言中,收集器通常在发布模式下更具侵略性;
  • 记忆的布局往往可能不同;
  • 内存的初始化可能不同(例如,可以在debugging模式下清零,或者在发布时更加积极地重新使用)。
  • 当地人可能被提升为注册版本,这可能会导致浮点值的问题。

过去我曾经被一些错误所困扰,在Debug版本中已经很好,但在Release版本中崩溃了。 有许多潜在的原因(当然包括那些已经在这个线程中总结),我已经被以下所有被抓住:

  • #ifdef _DEBUG中的成员variables或成员函数,以便debugging版本中的类是不同的大小。 有时#ifndef NDEBUG用于发布版本
  • 同样,还有一个不同的#ifdef恰好只存在于两个版本之一中
  • debugging版本使用系统库的debugging版本,尤其是堆和内存分配function
  • 在发布版本中内联函数
  • 包含头文件的顺序。 这不应该引起问题,但是如果你有像#pragma pack这样的东西没有被重置,那么这可能会导致讨厌的问题。 使用预编译头文件和强制include文件也会出现类似的问题
  • 高速caching:您可能拥有只在发布版本中使用的高速caching等代码,或者caching大小限制不同
  • 项目configuration:debugging和发布configuration可能有不同的构build设置(使用IDE时可能会发生这种情况)
  • 由于仅debugging代码而导致的竞争状况,计时问题和杂音副作用

我已经积累了多年来积累的debugging/发布漏洞底部的一些提示:

  • 如果可以的话,尝试在debugging版本中重现exception行为,甚至更好地编写一个unit testing来捕获它
  • 想想这两者之间有什么不同:编译器设置,caching,只能debugging的代码。 尽量减less这些差异暂时
  • 在优化closures的情况下创build一个发布版本(所以你更有可能在debugging器中获得有用的数据),或者优化的debugging版本。 通过最大限度地减lessdebugging和发布之间的变化,你更有可能能够找出造成错误的差异。

是的,如果你有条件编译,可能会有定时错误(优化的发行版本代码,非优化的debugging代码),内存重用与debugging堆。

它可以,特别是如果你在C领域。

一个原因可能是DEBUG版本可能会添加代码来检查stream浪指针,并以某种方式防止您的代码崩溃(或行为不正确)。 如果是这种情况,你应该仔细检查从编译器得到的警告和其他消息。

另一个原因可能是优化(这通常是发布版本和closuresdebugging)。 代码和数据布局可能已经过优化,例如,当您的debugging程序正在访问未使用的内存时,发布版本现在试图访问保留的内存,甚至指向代码!

编辑:我看到其他人提到它:当然,你可能有整个代码段有条件地排除,如果不编译在debugging模式。 如果是这样的话,我希望这真的是debugging代码,而不是程序本身的正确性的重要!

当然,例如,如果你使用类似的结构

 #if DEBUG //some code #endif 

在.NET中,即使不使用像#if DEBUG这样的条件编译,编译器在释放模式下的优化仍然比在debugging模式下更自由,这也会导致只发布错误。

在debugging与发布(/ MD vs / MDd)中,CRT库函数的行为有所不同。

例如,debugging版本通常预先填充您传递给指定长度的缓冲区,以validation您的声明。 示例包括strcpy_sstrcpy_s等。即使string更早终止,您的szDest最好是n个字节!

你需要提供更多的信息,但是,这是可能的。 这取决于你的debugging版本。 你可能有logging或额外的检查,不会被编译成发行版本。 这些只能debugging的代码path可能具有意想不到的副作用,它们会以奇怪的方式改变状态或影响variables。 debugging版本通常运行速度较慢,所以这可能会影响线程并隐藏竞争条件。 对于发布编译的直接优化也是如此,发布编译可能(虽然不太可能)可能会缩短优化的步伐。

没有更多的细节,我会假设“不好”意味着它不会在运行时编译或抛出某种错误。 检查是否有依赖于编译版本的代码,通过#if DEBUG语句或通过标记为Conditional属性的方法。

这是可能的,如果你有条件编译,所以debugging代码和发布代码是不同的,并且只有在发布模式中使用的代码有一个错误。

除此之外,这是不可能的。 debugging代码和发布代码的编译方式有所不同,如果在debugging器下运行代码的执行方式有所不同,但是如果这些差异之一导致性能差异以外的任何问题,则问题一直存在。

在debugging版本中,错误可能不会发生(因为时序或内存分配不同),但这并不意味着错误不存在。 也可能有其他一些与debugging模式无关的因素,这些因素会改变代码的时序,导致错误发生,但这一切都归结为如果代码是正确的,错误不会发生在任何情况下。

所以,不,只是因为你可以运行它没有得到一个错误的debugging版本不好。 如果在发布模式下运行时发生错误,那不是因为发布模式,这是因为错误是从一开始就存在的。

有编译器优化, 可以打破有效的代码,因为他们太积极了。

尝试编译你的代码,打开更less的优化。

这是可能的。 如果发生这种情况,并且没有涉及条件编译,那么你可以确定你的程序是错误的,并且只是在内存初始化或偶然的内存布局的情况下才工作在debugging模式下!

在一个非void函数中,所有的执行path应该以return语句结束。

在debugging模式下,如果您忘记用return语句结束这样的path,那么默认情况下该函数通常返回0。

但是,在发布模式下,您的函数可能会返回垃圾值,这可能会影响程序的运行方式。

我刚刚经历过,当我调用一个汇编函数,没有恢复寄存器的以前的值。

在“发布”configuration中,VS正在用/ O2进行编译,优化代码速度。 因此一些局部variables只映射到CPU寄存器(用于优化),这些寄存器与前述function共享导致严重的内存损坏。

无论如何,看看你是不是在代码中的任何地方间接干扰CPU寄存器。

我记得以前我们用c / c ++编译dll和pdb的时候。

我记得这个:

  • 添加日志数据有时会使bug移动或消失,或者出现完全的其他错误(所以这不是一个真正的select)。
  • 很多这些错误,由于在strcpy和strcat和char []等数组中的char分配…
  • 我们通过运行边界检查器并简单地修复了内存的alloc / dealloc问题。
  • 很多时候,我们系统地检查了代码并修改了一个char分配(就像所有的文件一样)。
  • 这肯定是与内存分配和pipe理以及debugging模式和发布模式的约束和差异有关的。

然后希望最好的。

我有时候暂时把dll的debugging版本交给了客户端,以便在处理这些错误的时候不要拖延生产。