在Windows上捕获访问冲突

我正试图捕捉我的应用程序中的所有未处理的exception,所以我可以保存一个日志文件,当他们发生。 这是使用Visual Studio 2013编译的64位Windows应用程序,用C ++编写。 为了testing,我使用由VS生成的默认C ++ Win32项目。

我通过使用SetUnhandledExceptionFilter注册一个处理程序来捕获所有exception。 这工作正常/大多数情况下,但不是全部。 所有的throw() – nexception都会被捕获,而且大多数硬件exception(如浮点或访问冲突)也是如此。 不触发处理程序的代码是:

std::vector<int> foo(5, 0); for (auto& f : foo) foo.erase(foo.begin() + 1); 

相反,我只是得到标准的Windows崩溃对话框,没有我的exception处理程序被调用。 如果我在Visual Studio中使用附加的debugging器运行它,但它会正确报告访问冲突exception。 其他types的访问冲突触发器也是如此:

 float* ptr = nullptr; float value = *ptr; 

上面的代码触发exception处理程序。

我已经尝试过使用try / catch或者捕获SIGSEGV信号,但是没有被第一个例子触发。 中止/终止信号也不会被调用。 总之,我没有办法通知当发生这种事故。

我想知道有什么办法可以在我的应用程序中得到某种types的通知之前,由于第一个例子造成的访问冲突崩溃? 由于VS似乎能够检测到它,我假设有一种方法。

编辑:我只是想澄清我在发布模式下运行的代码和第一个示例中的错误不是由debugging模式下的迭代器超出边界检查所造成的。

编辑2:我包括最简单的例子,我可以想出使用win32控制台应用程序。 在这里看到: http : //pastebin.com/8L1SN5PQ

确保在没有附加debugging器的情况下以释放模式运行它。

Solutions Collecting From Web of "在Windows上捕获访问冲突"

这些运行时错误的处理方式不同,它们不会产生SEH异常。 大致分为“编程错误”和“恶意软件攻击”之间。 而且,如果没有附加调试器,就像未被捕获的C ++异常一样,默认处理程序使用__fastfail()调用即时死亡。

你必须在main()函数中调用_set_invalid_parameter_handler()来改变它们的处理方式。 你可以在你的自定义处理程序中抛出一个C ++异常,或者调用RaiseException()来触发你的catch-em-all处理程序,或者直接在那里报告它们。 赞成后者,你想确保过程总是终止。

要小心,你的片段不是最好的例子。 当您在未启用迭代器调试的情况下构建程序时,这就是UB,就像使用默认设置的Release版本一样。 UB不保证你会得到一个SEH例外。 如果这样做,那么你将不得不非常仔细地写你的异常过滤器,它将被调用与仍然采取堆锁,所以基本的东西不能工作。 最好的办法是唤醒一个名为事件的警卫进程。 然后需要一个小型转储并终止程序。

您没有看到异常,因为它由C运行时在内部处理。 特别是它是一个边界检查不是访问冲突。

在调试器中运行它,我发现它是vector第242行:

  _DEBUG_ERROR("vector iterators incompatible"); 

哪个最终调用_CrtDebugReportW : https : _CrtDebugReportW

您可以使用_CrtSetReportMode控制_CrtDebugReportW的行为。

请注意,这在发布模式下不起作用,因为这些是调试模式边界检查。