我有一个 Windows 窗体应用程序 (.NET 4),它在我的开发计算机上运行良好,但在其他两台测试计算机上崩溃。我可以加载它在 VS2010 中创建的小型转储。
选择“使用混合调试”会导致 Visual Studio 明显无休止地滥用 CPU(我在大约 20 分钟后杀死了 devenv)。
当我“仅使用本机调试”时,它找不到源(即使我已将源镜像到与测试机相同的文件夹中)。它只是说:
0x793f5b8c 处未处理的异常
YourWinApp.exe.hdmp:0xC0000409:0xc0000409。
然后给我看
调用堆栈位置:clr.dll!793f5b8c()
我如何找出导致应用程序崩溃的原因?我可以在显示“通知 Microsoft”对话框时获取完整的故障转储吗?这会有帮助吗?
I have a Windows Forms application (.NET 4) that runs fine on my development machine but crashes on two other test machines. I can load the minidump that it creates in VS2010.
Choosing to "Debug with Mixed" leads to apparently endless (I killed devenv after about 20 minutes) abuse of the CPU by Visual Studio.
When I "Debug with Native Only", it can't find the source (even though I have mirrored the source in the same folder as on the test machine). It simply says:
Unhandled exception at 0x793f5b8c in
YourWinApp.exe.hdmp: 0xC0000409: 0xc0000409.
And then shows me
Call stack location: clr.dll!793f5b8c()
How would I find out what's causing the application to crash? Can I take a full crashdump whilst the "Notify Microsoft" dialog is being displayed, and would that help?
发布评论
评论(2)
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符号服务器”。
Minidump debugging was supposed to be majorly improved in VS2010. Haven't seen a lot of evidence for it myself yet, mixed-mode debugging looks as awkward as it was before when I did some quick tests. Don't take my word for it though. Native-only is however never going to show you a managed call stack.
Tackle this at the source. Write an event handler for AppDomain.CurrentDomain.UnhandledException and register it in your Main() method. Let it display the value of e.ExceptionObject.ToString() in, say, a message box. That gets you the managed stack trace of the exception. While that message box is displayed you could also snap the minidump, ought to get you closer to the crash location.
The particular exception you are getting is however definitely pointing to native C/C++ code. A buffer overflow that is corrupting the stack. Make sure you have the .pdb files for any native code your app uses. And setup the Microsoft symbol server so you get a good native stack trace from the minidump.
Edit: the fact that you don't get UnhandledException raised definitely points to stack integrity checking in the CRT. It was designed to not raise an exception but terminate the program immediately. Necessary behavior because the stack is compromised, the code cannot assume that it can be unwound safely. Given the crash location, it is likely that this check is actually done in the CLR code. I know this wasn't done in previous CLR versions but that might be different in the CLR version included with .NET 4.0
This is going to make it quite difficult to get a managed stack trace. There's a lot you can reverse-engineer from the unmanaged stack trace, as long as you setup the symbol server so that you'll get identifier names from the CLR stack frames. Post that stack trace in your question if you want help interpreting it. A bug in the CLR code is not unlikely btw, you may want to consider calling Microsoft Support. They will however need a consistent repro. They may make do with that all important stack trace if the repro is hard to come by. Setup the symbol server to get a good unmanaged stack trace. Easy in VS2010: Tools + Options, Debugging, Symbols, tick "Microsoft Symbol Servers".
如果应用程序有未处理的异常,您可以配置 procdump 来获取完整内存转储,您可以在 VS 或 Windbg 中对其进行调试,
并且小型转储具有作为 watson 存储桶的调用堆栈信息,这是来自 CLR 团队和我写过相同< /a>
关于您在事件查看器中看到的未处理异常的 watson 存储桶信息的简要说明
You configure procdump to get full memory dump if the application has unhandled exception ,which you can debug it in VS or Windbg
And the minidump has call-stack information as watson buckets, here is one from CLR team and I wrote about the same
A brief explanation on the watson bucket information that you see in event viewer for unhandled exception