如何查看导致 clr.dll 中崩溃转储的 C# 代码?

2024-04-14

我有一个 Windows 窗体应用程序 (.NET 4),它在我的开发计算机上运行良好,但在其他两台测试计算机上崩溃。我可以加载它在 VS2010 中创建的小型转储。

选择“使用混合调试”会导致 Visual Studio 明显无休止地滥用 CPU(我在大约 20 分钟后杀死了 devenv)。

当我“仅使用本机调试”时,它找不到源(即使我已将源镜像到与测试机相同的文件夹中)。它只是说:

0x793f5b8c 处未处理的异常你的WinApp.exe.hdmp:0xC0000409:0xc0000409。

然后给我看

调用堆栈位置:clr.dll!793f5b8c()

我如何找出导致应用程序崩溃的原因?我可以在显示“通知 Microsoft”对话框时获取完整的故障转储吗?这会有帮助吗?


VS2010 中的小型转储调试应该得到重大改进。我自己还没有看到很多证据,混合模式调试看起来和我之前做一些快速测试时一样尴尬。不过,请不要相信我的话。然而,仅限本机永远不会向您显示托管调用堆栈。

从源头上解决这个问题。为 AppDomain.CurrentDomain.UnhandledException 编写一个事件处理程序,并将其注册到 Main() 方法中。让它在消息框中显示 e.ExceptionObject.ToString() 的值。这将为您提供异常的托管堆栈跟踪。当显示该消息框时,您还可以捕捉小型转储,应该可以让您更接近崩溃位置。

然而,您得到的特定异常肯定指向本机 C/C++ 代码。缓冲区溢出正在破坏堆栈。确保您拥有应用程序使用的任何本机代码的 .pdb 文件。并设置 Microsoft 符号服务器,以便您从小型转储中获得良好的本机堆栈跟踪。

编辑:您没有引发 UnhandledException 的事实肯定表明 CRT 中的堆栈完整性检查。它的设计目的是not引发异常但立即终止程序。这是必要的行为,因为堆栈受到损害,代码不能假设它可以安全地展开。考虑到崩溃位置,此检查很可能实际上是在 CLR 代码中完成的。我知道以前的 CLR 版本中没有这样做,但 .NET 4.0 附带的 CLR 版本中可能有所不同

这将使获取托管堆栈跟踪变得非常困难。只要您设置符号服务器,以便从 CLR 堆栈帧获取标识符名称,您就可以从非托管堆栈跟踪进行很多逆向工程。如果您需要解释它的帮助,请在您的问题中发布该堆栈跟踪。顺便说一句,CLR 代码中的错误并非不可能,您可能需要考虑致电 Microsoft 支持。然而,他们需要一致的重现。如果很难获得重现,他们可能会使用所有重要的堆栈跟踪。设置符号服务器以获得良好的非托管堆栈跟踪。在VS2010中很简单:工具+选项,调试,符号,勾选“Microsoft符号服务器”。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何查看导致 clr.dll 中崩溃转储的 C# 代码? 的相关文章

随机推荐