【发布时间】:2016-01-07 08:08:58
【问题描述】:
我试图在我的应用程序中捕获所有未处理的异常,以便在它们发生时保存一个日志文件。这是使用 C++ 编写的 Visual Studio 2013 编译的 64 位 Windows 应用程序。为了测试,我使用的是 VS 生成的默认 C++ Win32 项目。
我通过使用 SetUnhandledExceptionFilter 注册处理程序来捕获所有异常。这适用于 /most/ 情况,但不是全部。捕获所有 throw()-n 异常,以及大多数硬件异常,如浮点或访问冲突。不触发处理程序的代码是:
std::vector<int> foo(5, 0);
for (auto& f : foo)
foo.erase(foo.begin() + 1);
相反,我只是得到标准的 Windows 崩溃对话框,而没有调用我的异常处理程序。但是,如果我在带有调试器的 Visual Studio 中运行它,它会正确报告访问冲突异常。其他类型的访问违规也会触发处理程序:
float* ptr = nullptr;
float value = *ptr;
上面的代码触发异常处理程序。
我也尝试过使用 try/catch 或捕获 SIGSEGV 信号,但都没有被第一个示例触发。中止/终止信号也不会被调用。简而言之,当崩溃发生时,我不会收到任何通知。
我想知道在我的应用程序由于第一个示例导致的访问冲突而崩溃之前,有什么方法可以在我的应用程序中获得某种通知?由于 VS 似乎能够检测到它,我假设有办法。
编辑: 我只是想明确一下,我在发布模式下运行代码,第一个示例中的错误不是由在调试模式下完成的迭代器越界检查引起的。
编辑2: 我包括了使用 win32 控制台应用程序可以想出的最简单的示例。在这里看到它: http://pastebin.com/8L1SN5PQ
确保在没有附加调试器的情况下以发布模式运行它。
【问题讨论】:
-
您需要查找 SEH 异常。这些不是正常 c++ 异常适用的情况。
-
我试过了。在 Visual Studio 中启用 SEH 的情况下使用 SEH __try/__except 会产生相同的结果。第一个示例不会触发异常,第二个会触发。
-
既然,正如汉斯所说,这不是一个好主意,我不会再花时间帮你做这件事了。相反:如果您正在调试,请在调试版本中运行应用程序并使用工具对其进行调试,直到没有错误为止。如果它是一个实时应用程序,并且您正在尝试调试偶尔发生的崩溃,请考虑部署调试版本或使用遥测服务。
-
感谢您迄今为止的帮助。遗憾的是,我无法向我们的用户分发调试版本,并且正在构建的产品非常庞大,因此肯定很难找到只有运行发布代码的用户才能找到的问题,我想涵盖所有基础并拥有错误报告至少包含调试日志。
标签: c++ windows visual-studio exception access-violation