【问题标题】:How to handle DirectX 11 driver crash如何处理 DirectX 11 驱动程序崩溃
【发布时间】:2018-11-12 22:38:23
【问题描述】:

首先,很抱歉这个问题被问了很多次,但我在网上找不到任何合适的答案。

我正在开发一款使用 DirectX 11.1 的游戏。我已经使用 Google 的 Crash-Pad library 的崩溃报告器将 Minidumps 上传到服务器,该服务器稍后可以使用 Visual Studio 打开或去符号化并打印当时每个线程的堆栈跟踪。崩溃的原因。

我总是收到一些有线堆栈跟踪的垃圾邮件,这些堆栈跟踪深入到驱动程序 dll 中(当然不能去符号化),我一直认为这些堆栈跟踪与驱动程序崩溃有关。

Thread 10224 Crashed:
0   igd10iumd64.dll                 0x7ffbddcb4cba      <unknown>
1   igd10iumd64.dll                 0x7ffbddcae78e      <unknown>
2   igd11dxva64.dll                 0x7ffbaef99377      <unknown>
3   igd10iumd64.dll                 0x7ffbddcae2f9      <unknown>
4   igd10iumd64.dll                 0x7ffbddd89e17      <unknown>
5   igd11dxva64.dll                 0x7ffbaef73c5c      <unknown>
6   igd11dxva64.dll                 0x7ffbaef7314d      <unknown>
7   igd11dxva64.dll                 0x7ffbaef3efcf      <unknown>
8   igd11dxva64.dll                 0x7ffbaeff158a      <unknown>
9   igd11dxva64.dll                 0x7ffbaefe8cf6      <unknown>
10  igd11dxva64.dll                 0x7ffbaefe96b8      <unknown>

我现在的问题是,在典型的 DirectX 应用程序中,您如何处理此类崩溃并确保您的应用程序健壮且不会崩溃? (即使我需要重新创建整个 D3D11 设备)

在MSDN guide 之后的设备移除和重置 (DXGI_ERROR_DEVICE_REMOVED &amp;&amp; DXGI_ERROR_DEVICE_RESET) 情况下,我已经在处理标准 DXGI 返回代码

谢谢

编辑:我不介意退出我的应用,我只是想向用户解释我的应用遇到了致命错误,现在将退出(尽可能正确)

【问题讨论】:

  • 如果您要求以允许应用程序继续运行的方式处理此类崩溃,那么答案将是:没有这种方法。如果您要求一种避免错误的通用方法,那么问题就太宽泛了。另请注意,DXGI_ERROR_DEVICE_REMOVED 和 DXGI_ERROR_DEVICE_RESET 不是现金或某种致命错误的指标,应由您的应用程序正确处理。
  • 我正在寻找一种方法来优雅地处理这些崩溃并正确退出我的游戏(使用某种用户信息:win32 弹出窗口?)
  • 您可以从父进程运行游戏,当游戏进程崩溃时,该父进程会显示信息弹出窗口。
  • 这就是 Crashpad 在某种程度上正在做的事情(他们观察我的过程)。我只是想知道广义上的 AAA 游戏引擎有多大?

标签: c++ crash directx directx-11


【解决方案1】:

捕获崩溃和终止的最简单方法是在整个主函数周围使用结构化异常处理程序。这将捕获访问冲突、被零除和其他可能导致崩溃的硬错误。从那里,您可以在终止进程之前显示一个说明崩溃性质的弹出窗口。

请注意,SEH 不允许析构函数运行。通常,这是一件坏事,但在这里你无论如何都会杀死进程,所以这不是什么大问题。但是,在对象的构造函数中获取的任何锁都不会在执行 SEH 处理程序时被释放。不仅如此,如果对象被分配在堆栈上,它们本身将不再存在,从而阻止了任何类型的真正清理。

同样,上述问题在这里不是问题,因为您的进程正在崩溃。数据损坏现在无关紧要,因为该过程已经 FUBARed。您需要做的就是弹出一个消息框,说明您已崩溃,保存您绝对需要的任何信息(此处不要使用锁,因为锁定状态现在是不确定的),然后 terminate(不退出)进程(如果退出,将发送进程/线程分离通知,这可能会导致死锁)。

这可以扩展到您显式创建的所有其他线程,方法是让线程从一个公共入口点开始,进入一个 SEH 框架,然后分支到它们各自的任务。

【讨论】:

    猜你喜欢
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多