【发布时间】:2013-02-10 02:36:45
【问题描述】:
我正在使用 Visual Studio 2010 在 C++ 中开发 Win32 应用程序。在调试模式下运行时,应用程序运行良好并在退出时正确关闭。然而,在发行版中,程序运行良好,但在应用程序关闭时出现未处理的异常:Application.exe 中 0x009C19F5 处的未处理异常:0xC0000005:访问冲突读取位置 0x00297628。
然后调试器在 std::local 的析构函数中中断 xlocale:
~locale() _THROW0()
{ // destroy the object
if (_Ptr != 0)
_DELETE_CRT(_Ptr->_Decref()); // breaks here with unhandled exception
}
我相信,在我的主函数返回并在某处调用 exit(0) 之后,上面的代码正在运行。这是我崩溃时的调用堆栈:
Application.exe!std::locale::~locale() Line 411 C++
Application.exe!doexit(int code, int quick, int retcaller) Line 567 C
Application.exe!exit(int code) Line 393 C
Application.exe!__tmainCRTStartup() Line 284 C
kernel32.dll!@BaseThreadInitThunk@12() Unknown
ntdll.dll!___RtlUserThreadStart@8() Unknown
ntdll.dll!__RtlUserThreadStart@8() Unknown
我正在使用 Microsoft 的应用程序验证程序,并且正在运行 _CrtCheckMemory( );经常检查堆损坏,我没有看到在调试或发布模式下检测到任何东西。在我的任何来源中,我也完全没有弄乱 std::locale 。
我最近将解决方案的设置切换为默认使用 unicode,而不是 256 个一字节大小的字符。但是现在在 unicode 和多字节设置之间来回切换似乎不会影响发布时退出时的崩溃。
有人知道发生了什么吗?
【问题讨论】:
-
UB 可能在某个地方。
-
嗯,我无法找到一种方法来追踪未定义行为的根源。
-
您是否有任何使用 stdio 或 iostreams 等的全局变量(或静态变量)?
-
是的,实际上,我有一个自定义反射系统,它使用全局变量进行注册。其中一些执行文件序列化,并将 ostream 或 istream 的引用作为参数。
-
检查程序中的所有指针故障,确保只有在最后一个用户离开时才正确处理所有内容。我不知道 valgrind 之类的东西(跟踪所有分配,并最终为您提供不一致的摘要)可用于 Windows。