为什么我要在没有调试的情况下启动调试版本?

4

在没有调试的情况下启动调试版本是否有益处(与没有调试的发布版本相比)?当我在调试发布版本时会错过什么(与调试调试版本相比)?


它不支持断点、监视器或任何其他IDE调试工具。我相信还有更多,所以我不会把这作为答案。 - GManNickG
4个回答

7

除了IDE之外,调试版本的最大优点:

  • 启用了断言,以及您在调试相关预处理器部分中编译的其他诊断代码。
  • 堆栈跟踪和变量监视正常工作,因此您可以让测试人员向您发送崩溃转储,并在稍后在IDE中进行调试。

最大的缺点:

  • 执行速度较慢,内存消耗更高,文件大小更大。
  • 有些错误只有在使用完全优化的编译时才能显现。这是因为内存分配在发布版本中的工作方式不同。

许多公司将调试版本分发给alpha和beta测试人员,然后切换到发布版本。


在优化后的发布版本中进行调试会非常误导关于监视变量值。优化器往往不会为变量实际保留空间(仅使用寄存器),以便为几个连续的变量重复使用同一内存区域...这导致调试器显示变量的错误值,即使变量具有正确的值。 - Didier Trosset

1

补充Adrians 答案,并且在谈论调试与发布版本时,有一些因素会影响您的构建:

以下是一些影响您的构建的因素:

  • 您链接到调试或发布运行时库(/MD vs. /MDd)
  • NDEBUG(发布模式)或_DEBUG(调试模式)被定义
  • _SECURE_SCL(或某个等效项)被定义(或未定义)
  • 启用编译器优化(在某种程度上)

“调试构建”通常包括_DEBUG_SECURE_SCL=1/MDd和所有编译器优化禁用。这将导致“最安全”,“最多检查”的执行模式,但也应该是您可获得的最慢版本。 速度和安全性应完全独立于是否在调试器下运行程序! - 调试构建为您提供了最大的安全性和错误捕获网络,完全独立于程序是否附加到调试器。

接下来是一个未经优化的发布版本构建: 也就是说,您拥有所有发布模式设置(NDEBUG、_SECURE_SCL=0等),但您禁用了所有编译器优化。这对于测试很好,因为性能不会被拖垮太多,您可以调试它。再次强调,这个的有用性独立于您是否在调试器下运行程序。
最后是完全优化。(/Ox + 完全内联 + 可能整个程序优化):虽然出于性能原因,这是您想要发布的内容,但很可能您公司中没有足够的人员能够真正进行调试。也就是说,鉴于崩溃转储,某人极有可能需要一定的asm知识和编译器输出才能理解崩溃转储(甚至是某些随机断点,在实际运行时通过调试器)。同样,完全优化的利弊独立于是否在调试器下启动/运行程序。

0

在不进行调试的情况下启动调试版本,可以带给你以下好处:如果一个容器使用无效的索引进行了索引操作,你会得到断言失败的结果,在发布模式下你会得到未定义的行为。这是一个想法。当你在发布模式下进行调试时,你会错过源代码和汇编代码之间不再有对应关系的事实,因为优化器已经运行。因此在发布模式下进行调试更加困难。


0

我将提供一个最近的经验,但我无法解释 -- 有时候当我运行我的应用程序时,在IDE中运行时会出现未处理的异常。问题是,我知道我的异常正在被处理,并且我也知道我没有在抛出异常时断点(通过CTRL-D,E)。如果我按F5几次,我的错误处理程序最终会捕获异常并正确处理它。

这个问题困扰了我几周,所以当我不想中断执行时,我会在IDE外部运行,如果需要的话稍后再附加到进程上。

如果你真的需要在IDE外部运行时看到调试输出,并且你没有使用像log4net这样的东西来捕获所有内容,那么你可以使用DebugView


请注意,在调试器下启动时的一个区别是您的应用程序将使用不同的堆(调试堆)。这仅在使用调试器启动时才会执行,并且与prg是构建发布还是调试版本无关。 - Martin Ba
我有点困惑,我只是给出了一个例子,以帮助原帖作者理解我曾经在调试器之外运行过调试版本的情况。我并没有提到调试版和发布版之间的任何区别。 - Dave

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接