所以我刚刚遵循了为发布模式启用调试符号的建议,在启用调试符号后,禁用优化并发现如果符号符合发布模式,断点确实有效,我发现自己想知道......
- Debug模式的目的不就是帮你找bug吗?
- 如果调试模式让错误从你身边溜走,为什么还要打扰它呢?
有什么建议吗?
所以我刚刚遵循了为发布模式启用调试符号的建议,在启用调试符号后,禁用优化并发现如果符号符合发布模式,断点确实有效,我发现自己想知道......
有什么建议吗?
事实上,没有发布模式或调试模式之类的东西。只有不同的配置启用了不同的选项。Release 'mode' 和 Debug 'mode' 只是常见的配置。
您所做的是修改发布配置以启用一些通常在调试配置中启用的选项。
根据您启用的选项,启用这些选项会使二进制文件更大更慢。
您启用的这些选项越多,就越容易找到错误。我认为您的问题应该是“为什么要使用发布模式?” 答案是它更小更快。
调试模式不会“让错误从你身边溜走”。它插入检查以捕获大量错误,但这些检查的存在也可能隐藏某些其他错误。所有的错误检查代码都会捕获很多错误,但它也充当填充,并且可能隐藏细微的边界错误。
因此,这本身就应该有充分的理由同时运行两者。MSVC在调试模式下执行许多额外的错误检查。
此外,许多调试工具,例如assert
依赖于NDEBUG
未定义,在调试版本中就是这种情况,但在默认情况下,在发布版本中则不然。
优化将被关闭,这使得调试更容易(否则代码可能会以奇怪的方式重新排序)。还可以包含诸如 assert() 等条件代码。
除了您的应用程序在发布模式下非常可调试之外,MSVC 运行时库不是很好,其他一些库也不是。
例如,调试堆在分配的内存周围添加无人区标记以捕获缓冲区溢出。MSVC 使用的标准库断言迭代器有效性。以及更多。
由于优化器导致的错误并非闻所未闻。但通常它们暗示了更深层次的问题,例如,volatile
在需要时不使用会导致优化器错误(优化比较并使用缓存结果)。
归根结底,在早期版本中包含调试符号可以帮助您在部署后追踪错误。
现在,直接回答您的问题:
assert()
在发布模式下被剥离的 s。volatile
错误)仅在调试模式下隐藏:它们仍然存在,只是更难触发。在您的应用程序中包含完整符号包括有关构建机器的重要信息(嵌入路径等)。
建议是在发布版本中包含“仅 PDB”符号(不包含文件、行和局部变量符号)并启用优化。并且调试版本没有优化和完整的符号。
并且(如其他答案中所述)常见的子表达式消除和指令重新排序可以使调试变得有趣(下一步移动到第 n、n+2、n+1 行...)。
优化是调试的噩梦。一旦我有这个for循环的应用程序
for (int i = 0; i < 10; i++)
{
//use i with something
}
我在调试时总是 0。但是将其输出到控制台表明它确实增加了