【问题标题】:Two identical call stacks differ as they are shown by debugger两个相同的调用堆栈不同,因为它们由调试器显示
【发布时间】:2015-10-17 17:54:46
【问题描述】:

在我的代码中我有一个错误:我锁定std::mutex 两次。

我总是运行我的应用程序的调试版本。

有2个运行案例:

  1. 我在调试器下运行它。在这种情况下,我得到以下堆栈跟踪异常。没关系。

  1. 我只是在没有调试器的情况下运行它。我得到 Microsoft Visual C++ 运行时库调试错误窗口。

然后我将调试器连接到进程并单击重试。 我得到以下堆栈跟踪,实际上什么也没显示:

完全相同的错误。两个不同的堆栈跟踪。为什么?

补充 #1:我正确指定了所有符号(包括 Microsoft Windows 的)。

【问题讨论】:

    标签: c++ windows visual-studio-2013 crash-dumps


    【解决方案1】:

    在第一个堆栈中,您位于应用程序中引发异常的位置。我猜你在调试器中设置了某种形式的“异常中断”。

    在第二个堆栈中,您位于应用程序中捕获异常的位置。这发生在加注之后,在一个 catch 块中。看起来您在 _Call_func 框架的 catch 块中。

    所以这两种情况看起来不同,因为它们不同的。虽然是同一事件,但你在不同的时刻看待它。

    如果我冒昧地猜测您有某种回调,其中您没有 try/catch 块并让异常传播到 CRT,由于未处理的异常而尽职尽责地中止进程。

    必读:A Crash Course on the Depths of Win32™ Structured Exception Handling 了解这两个时刻之间发生了什么,以及第一个堆栈如何过渡到第二个堆栈,如果让我们放松并继续。

    【讨论】:

      【解决方案2】:

      Exception Dispatching 导致此行为:

      当用户模式代码发生异常时,系统使用以下搜索顺序查找异常处理程序:

      1. 如果进程正在调试,系统会通知调试器。有关详细信息,请参阅调试器异常处理。
      2. 如果进程没有被调试,或者关联的调试器没有处理异常,系统会尝试通过搜索发生异常的线程的堆栈帧来定位基于帧的异常处理程序。系统先搜索当前堆栈帧,然后以相反的顺序搜索前面的堆栈帧。
      3. 如果找不到基于帧的处理程序,或者没有基于帧的处理程序处理异常,但正在调试进程,系统会再次通知调试器。
      4. 如果进程没有被调试,或者关联的调试器没有处理异常,系统会根据异常类型提供默认处理。对于大多数例外情况,默认操作是调用 ExitProcess 函数。

      在第一个示例中,调试器在 1) 处停止,在第二个示例中,系统在 4) 处停止并且通常会终止进程。但是由于您安装了 Visual Studio,它认为您可能是开发人员并要求您进行调试。

      在 1) 抛出异常的地方和 4) 进程即将死亡的地方,发生了很多事情,调用堆栈不同。

      【讨论】:

        猜你喜欢
        • 2018-03-30
        • 2012-06-28
        • 1970-01-01
        • 2017-12-05
        • 2021-11-20
        • 2021-12-06
        • 2014-11-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多