我有一个大型 WPF 应用程序,它也使用 C++ 库来实现某些功能。
应用程序有时会因 C++ 代码中未处理的异常或访问冲突而崩溃。编辑:由于未处理的 C# 异常,它有时也会在主线程上崩溃。
我已经使用以下处理程序来记录有关崩溃的信息:
- DispatcherUnhandledException
- TaskScheduler.UnobservedTaskException
- AppDomain.CurrentDomain.UnhandledException
(编辑:我注册这些事件与此示例非常相似:https://stackoverflow.com/a/46804709/2523211)
但是,如果我启用了转储文件创建并且达到了这些函数(即在未处理的异常场景中),则原始异常的堆栈已经自行展开,并且我无法检查调用堆栈以及错误发生时的内存和线程。
我显然可以在作为这些处理程序的参数获得的异常中看到堆栈跟踪本身,但仅此而已,我希望看到引发异常时代码的状态。
(编辑:调用堆栈仅显示我处于调度程序框架中,并且在异常发生时我无法检查应用程序的变量和其他内存状态。我可以使用异常本身的数据并查看来自它的调用堆栈,但这不足以重现或真正理解异常发生的原因)
如果我不订阅这些事件,那么什么都不会改变,我仍然看不到转储文件中的原始调用堆栈。 (编辑:因为我只在调度程序中获得调用堆栈)
我也尝试过设置 e.Handled = false
但我认为这无论如何都是默认值。
是否有某种方式向 WPF 的调度程序指示,或者问题可能出在其他地方,以便如果确实发生异常,让它一直向上传播,以便在为其创建转储时,我将能够有用的转储文件吗?
最佳答案
您所要求的内容在 dotnet 内是不可能实现的。您希望在不展开堆栈的情况下处理异常,并转储核心以供以后分析。
但是,您可以使用 WinDbg API 在 dotnet 之外执行此操作。幸运的是,WinDbg API 有一个名为 clrmd 的包装器。 .
只需实现IDebugEventCallbacks.Exception
,然后调用WriteDumpFile。
但是,您应该注意。该解决方案将在生产中附加一个调试器。因此产生了相关的成本。
关于c# - 具有原始异常调用堆栈和内存的 WPF 故障转储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70446369/