我刚刚按照启用Release模式下的调试符号的建议去做了,启用调试符号后禁用优化,发现如果使用Release模式编译符号,则断点可以正常工作,这让我想到...
- Debug模式的目的不是帮助你找到bug吗?
- 如果Debug模式会让bug漏掉,那还有什么意义呢?
请问您有什么建议吗?
我刚刚按照启用Release模式下的调试符号的建议去做了,启用调试符号后禁用优化,发现如果使用Release模式编译符号,则断点可以正常工作,这让我想到...
请问您有什么建议吗?
实际上,不存在所谓的“发布模式”或“调试模式”,只有不同的配置和不同的选项启用。 “发布模式”和“调试模式”只是常见的配置。
你所做的是修改发布配置以启用通常在调试配置中启用的某些选项。
启用这些选项会使二进制文件变得更大且更慢,具体取决于您启用的选项。
启用的选项越多,查找错误就越容易。我认为你的问题应该是“为什么要使用发布模式?”答案是它更小更快。
调试模式不会“让漏洞溜过你”。它插入检查以捕获大量的漏洞,但这些检查的存在也可能隐藏某些其他漏洞。所有错误检查代码都可以捕获很多错误,但它也作为填充物,并可能隐藏微妙的边界错误。
因此,这本身就足以运行两者了。MSVC在调试模式下执行大量的附加错误检查。
此外,许多调试工具,例如assert
依赖于未定义NDEBUG
,这是调试构建中的情况,但默认情况下不适用于发布构建。
优化将被关闭,这样调试更容易(否则代码可能会以奇怪的方式重新排序)。此外,条件代码,如assert()等,也可以包含在内。
由于优化器而导致的错误并不罕见;但通常它们暗示着更深层次的问题,例如,在需要使用volatile
时没有使用会导致优化器错误(优化比较并使用缓存结果)。
归根结底,在早期版本中包含调试符号可以帮助您在部署后跟踪错误。
现在,直接回答您的问题:
assert()
。volatile
错误)只在调试模式下隐藏:它们仍然存在,只是更难触发。在应用程序中包含完整符号,可以包含有关构建机器的重要信息(路径等嵌入其中)。
建议在发布版本中使用“仅PDB”符号(不包括文件、行和本地变量符号),并开启优化。而调试版本没有优化和完整符号。
如其他答案所述,公共子表达式消除和指令重排序可能会使调试变得有趣(移动到下一行时,会跳转到n、n+2、n+1行...)。
优化对于调试来说是一场噩梦。我曾经有一个应用程序,其中包含了这个for循环。
for (int i = 0; i < 10; i++)
{
//use i with something
}
在调试中,我一直是0。但将其输出到控制台后发现它确实增加了。