【问题标题】:Catch c++ Access Violation exception捕获 c++ 访问冲突异常
【发布时间】:2022-01-07 15:06:51
【问题描述】:

在我的代码的某些部分引发了 c++ 访问冲突错误。我想“抓住”它并记录故障线,以便进一步调查。 我在这个线程中尝试了第一个答案: Catching access violation exceptions?

不幸的是,到目前为止还没有运气。我在 Visual Studio 2019 中使用调试模式。有人知道如何记录故障线吗?

【问题讨论】:

  • 不要抓住它。访问冲突意味着您的程序已损坏。如果你确实拦截了信号,丢弃它,然后继续,你就无法知道程序处于什么状态。
  • 您想要做的是使用 Visual Studio 的同类最佳调试器来帮助您跟踪导致崩溃的错误并消除错误。如果您可以显示代码,我们会很高兴地通过帮助修复您的问题来获得额外的声誉。
  • 您应该只捕获这些异常以生成转储文件,然后终止您的程序。 Visual Studio 对此有一个 __try __except 机制。

标签: c++ windows visual-studio exception access-violation


【解决方案1】:

您所指的“访问冲突”不会发生在格式良好的代码中。它始终是未定义行为的结果。

当这种情况发生时,您的程序状态是未知的,并且以某种未指定和未知的方式损坏。您不能再期望在程序中完成任何有意义的任务,因为程序的状态不再是已知的。我想如果操作系统以只读方式保护程序的代码段,您可以依靠实际代码完好无损,但堆栈处于未知状态,您可以忘记堆的所有内容,它的状态是完全未知的.

从有缺陷的程序中提取任何有用的诊断信息的唯一有意义的方法是使用外部调试器从外部视图分析和检查该点的程序状态的冻结快照。

【讨论】:

    【解决方案2】:

    在 Windows 上,您可以使用 __try ... __except 来执行此操作,如下面的简化示例所示:

    __try
    {
        * (int *) 0 = 0;
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        std::cout << "Exception caught\n";
    }
    

    Microsoft 将此机制称为“结构化异常处理”,它比 Unix 上的信号要强大得多(而且确实可用),如果您愿意,我鼓励您了解更多有关它的信息这种事:

    https://docs.microsoft.com/en-us/cpp/cpp/try-except-statement?view=msvc-170

    我用它来捕获表现不佳的 ASIO 驱动程序中的异常,否则这些异常会导致我的应用程序崩溃。

    【讨论】:

    • 不是找到故障点的直接方法,您在异常处理程序中,并且可能远离崩溃现场,但应该有助于进行几轮分而治之帮助您放大崩溃。真正的错误在哪里......这总是一个问题。
    • 嗨,保罗,感谢您的回答。假设在您的 __try 子句中您调用了另一种方法,而该方法又调用了其他方法。我如何找到引发错误的行,这是我感兴趣的,也是我问题的重点?再次感谢您抽出宝贵时间回答。
    • 我尝试在 filter 方法中使用 booststacktrace() 但没有运气。
    • 其实我想通了。这行得通。谢谢。
    猜你喜欢
    • 2010-10-02
    • 2010-11-01
    • 2012-11-14
    • 1970-01-01
    • 2019-08-16
    • 2015-08-28
    • 2023-03-19
    • 2016-03-27
    相关资源
    最近更新 更多