捕获 Windows 上的访问违规

2023-12-28

我试图捕获应用程序中所有未处理的异常,以便在发生异常时可以保存日志文件。这是一个使用 Visual Studio 2013 编译的 64 位 Windows 应用程序,用 C++ 编写。为了进行测试,我使用 VS 生成的默认 C++ Win32 项目。

我通过使用 SetUnhandledExceptionFilter 注册处理程序来捕获所有异常。这适用于/大多数/情况,但不是全部。所有 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 http://pastebin.com/8L1SN5PQ

确保在没有附加调试器的发布模式下运行它。


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

你必须打电话_set _invalid_parameter 处理程序() https://msdn.microsoft.com/en-us/library/a9yf33zb.aspx在你的 main() 函数中改变它们的处理方式。您可以在自定义处理程序中抛出 C++ 异常,或者调用 RaiseException() 来触发 catch-em-all 处理程序,或者直接报告它们。倾向于后者,您希望确保进程始终终止。

请注意,您的代码片段不是最好的示例。当您在未启用迭代器调试的情况下构建程序(例如使用默认设置的发布构建)时,这就是 UB。 UB 不保证您会获得 SEH 例外。如果确实如此,那么您必须非常仔细地编写异常过滤器,它将在仍保留堆锁的情况下调用,因此基本的东西无法工作。最好的方法是用命名事件唤醒守护进程。然后进行小型转储并终止程序。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

捕获 Windows 上的访问违规 的相关文章

随机推荐