2

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

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

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

YourWinApp .exe.hdmp 中0x793f5b8c处的未处理异常 :0xC0000409:0xc0000409。

然后给我看

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

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

4

2 回答 2

6

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

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

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

编辑:你没有得到 UnhandledException 的事实肯定指向 CRT 中的堆栈完整性检查。它旨在引发异常而是立即终止程序。必要的行为,因为堆栈被破坏,代码不能假设它可以安全地展开。给定崩溃位置,该检查很可能实际上是在 CLR 代码中完成的。我知道这在以前的 CLR 版本中没有完成,但在 .NET 4.0 中包含的 CLR 版本中可能会有所不同

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

于 2010-07-23T17:28:29.290 回答
0

如果应用程序有未处理的异常,您可以 配置procdump以获取完整的内存转储,您可以在 VS 或 Windbg 中对其进行调试

minidump 有调用堆栈信息作为 watson 桶,这是CLR团队的一个,我写的差不多

关于您在事件查看器中看到的未处理异常的 watson 存储桶信息的简要说明

  1. 文件名
  2. exe程序集版本
  3. Exe 程序集时间戳
  4. 全名
  5. 错误的程序集版本
  6. 错误装配时间戳
  7. 错误装配方法定义
  8. 导致异常的错误方法 IL 指令
  9. 异常类型
于 2010-07-27T14:46:42.103 回答