我有一个使用 Visual Studio 2005 C++ 编写的程序,在发布模式下与调试模式下运行不同。在发布模式下,出现了(表面上)间歇性崩溃的情况。在调试模式下,程序不会崩溃。有哪些原因会导致 Release 构建与 Debug 构建不同?
值得一提的是,我的程序相当复杂,使用了多个第三方库进行 XML 处理、消息传递等操作...
谢谢!
我有一个使用 Visual Studio 2005 C++ 编写的程序,在发布模式下与调试模式下运行不同。在发布模式下,出现了(表面上)间歇性崩溃的情况。在调试模式下,程序不会崩溃。有哪些原因会导致 Release 构建与 Debug 构建不同?
值得一提的是,我的程序相当复杂,使用了多个第三方库进行 XML 处理、消息传递等操作...
谢谢!
#ifdef DEBUG
#define Log(x) cout << #x << x << "\n";
#else
#define Log(x)
#endif
if (foo)
Log(x)
if (bar)
Run();
在发布版本中,if (foo && bar) 将被求值。
编译器错误 这种情况真的几乎不会发生。嗯——其实也有可能会发生,但在大部分职业生涯中,您最好假设它不会发生。在与VC6合作的十年中,我只发现了一个问题,我仍然坚信这是未修复的编译器错误,相比于使用标准不足的模式(即所谓的“经文”)的数十个模式(甚至数百个实例)。
在调试版本中常常启用断言和/或调试符号。这可能会导致内存布局不同。如果出现错误指针、数组溢出或类似的内存访问问题,你可能会在一种情况下访问关键的坏内存(例如函数指针),而在另一种情况下只是访问一些非关键的内存(例如仅文档字符串被破坏)。
没有明确初始化的变量在发布版本中可能会被清零。
正式版构建(希望如此)比调试版构建运行更快。如果您使用多个线程,则可能会看到更多交错,或者仅有一个线程比其他线程运行得更快,这在调试构建中可能没有注意到。
发布版本通常在编译器中启用了优化,而调试版本通常没有。
在某些语言或使用许多不同库时,这可能会导致间歇性崩溃 - 尤其是当所选的优化级别非常高时。
我知道这适用于gcc C ++编译器,但我不确定微软的编译器是否也是如此。
我不久前也遇到过类似的问题,最终发现是由于在发布版本中堆栈的处理方式不同而引起的。其他可能会有所不同的因素包括:
https://web.archive.org/web/20090503153840/https://www.debuginfo.com/tips/userbpntdll.html
由于调试版本会添加保护字节,因此您可能能够“安全地”访问数组(特别是动态数组)之外越界的内存,但这将在发布版本中导致访问冲突。这种错误可能会被忽略,导致堆栈损坏,并可能在与原始错误无关的地方发生访问冲突。https://web.archive.org/web/20090210190738/https://support.microsoft.com/kb/286470