【问题标题】:Why catch an Access Violation?为什么要捕获访问冲突?
【发布时间】:2012-06-19 20:56:22
【问题描述】:

与 C++ 异常不同,访问冲突表明您的应用程序运行时受到威胁,因此您的应用程序的状态是未定义的。在这种情况下,最好的办法是退出您的应用程序(通常为您完成,因为它会崩溃)。

我注意到有可能捕获这些异常之一。例如,在 Microsoft Visual C++ 中,您可以使用 /EHa__try/__catch 来执行此操作。

那么,您想要抓住它们的原因是什么?据我了解,您的应用程序无法恢复。

【问题讨论】:

  • 当您崩溃时,您可能正在做一些通常令用户不愉快的事情。例如,您可能出于某种原因禁用了他们的任务栏。您需要确保在完成之前将其反转。
  • 但是如果运行时受到损害,继续清理代码的可能性有多大?
  • 我想可能发生的最坏情况是您的应用程序会崩溃。 ;-)
  • 希望对操作系统的一个函数调用能够通过,并且用户至少再次拥有一个可用的任务栏。

标签: c++ error-handling access-violation


【解决方案1】:

您可以从访问冲突中恢复。

例如,您可以通过使用VirtualAlloc 分配一些地址空间来创建一个动态数组,但将其指向的内存标记为不存在。然后,当您尝试使用某些内存时,您会捕获访问冲突,映射发生访问的内存页面,然后重试导致冲突的指令。

【讨论】:

  • 当然,当您使用这种深度魔法时,您和所有其他相关方都必须知道他们在做什么。否则,bad stuff 会发生。
【解决方案2】:

一个原因可能是编写故障转储文件;您将对其有更多的控制权,并能够编写您想要的确切类型。例如,在 Windows 中,您可以调用 MiniDumpWriteDump 来执行此操作。

【讨论】:

  • 在这种情况下,这似乎是一个人最可能想做的事情。不过,为其他给出合理答案的人+1。另外,一位同事将我引向了 Doug Harrison 的一篇文章的镜子,其中包含一些很好的信息:360doc.com/content/11/0411/10/6287626_108773107.shtml
【解决方案3】:

无法保证您的应用在所有访问违规后都保持稳定。但它可以稳定或在一段时间后恢复,因此捕获访问冲突让您有机会:

  1. 通知用户出现问题
  2. 让用户尝试保存工作
  3. 尝试恢复
  4. 记录诊断信息
  5. 以你想要的方式退出,而不是消失。

一个典型的例子是从插件捕获异常的主机应用程序。这样主机应用程序(例如 Photoshop)可以告诉用户“Plugin X 崩溃,Photoshop 不稳定……您应该保存您的工作,然后重新启动 Photoshop。”

请注意,这与 C++ 异常处理不同,后者根本不表示不可恢复的错误,而是更多的堆栈展开功能。

【讨论】:

    【解决方案4】:

    我认为最好优雅地崩溃并让用户知道发生了什么,而不是让应用程序消失。

    【讨论】:

      【解决方案5】:

      如果您的应用程序出现访问冲突,您可能无法恢复,也可能无法恢复。如果您的应用程序处于未定义状态,例如,您破坏了您的堆栈,您就完成了。

      从失控指针读取可能不会损坏您的应用程序,并且您可能可以从中恢复。

      无论哪种方式,它发生的事实都表明您的代码中存在错误,因此您应该捕获错误并转储您可以帮助您调试问题的状态,而不是尝试恢复。

      【讨论】:

      • 不幸的是,我们中的许多人编写与其他平台交互的代码,并且错误存在于其他代码中。如果可能的话,最好隔离这些并尝试继续。
      猜你喜欢
      • 2012-05-05
      • 2010-10-02
      • 1970-01-01
      • 2022-01-07
      • 2016-01-07
      • 2010-11-01
      • 2010-12-02
      • 1970-01-01
      相关资源
      最近更新 更多