在Visual Studio中调试Dump文件

57

我正在使用Visual Studio 2010专业版和Windows Vista。

首先,这是我的代码。你可以看到,它会使程序崩溃!

using System;

namespace Crash
{
    class Program
    {
        static void Main(string[] args)
        {
            string a = null;

            if (a.Length == 12)
            {
                // ^^ Crash
            }
        }
    }
}
程序将在if语句处崩溃。现在,我想找出它是否是在该if语句上崩溃。
如果我从Visual Studio中“开始而不调试”,Crash.exe会崩溃。它使用1,356kb的内存。我得到了关闭程序/调试的Vista选项。如果我选择调试,我可以打开Visual Studio的新实例,并指向if语句上的NullReferenceException。这很好。
现在让我假设它在另一台计算机上崩溃,然后我让他们通过任务管理器给我一个转储文件。它有54,567kb。为什么这么大!太庞大了!无论如何,我对此(略微)不太感兴趣。
如果我使用Windbg打开该转储文件,对于我这个没有经验的人来说,几乎没有什么有用的信息:
Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.


Loading Dump File [C:\Users\Richard\Desktop\Crash.DMP]
User Mini Dump File with Full Memory: Only application data is available

Symbol search path is: SRV*C:\SYMBOLS*http://msdl.microsoft.com/download/symbols
Executable search path is: 
Windows Server 2008/Windows Vista Version 6002 (Service Pack 2) MP (4 procs) Free x86 compatible
Product: WinNt, suite: SingleUserTS Personal
Machine Name:
Debug session time: Sat Jan 15 11:07:36.000 2011 (UTC + 0:00)
System Uptime: 0 days 4:24:57.783
Process Uptime: 0 days 0:00:05.000
........................
eax=002afd40 ebx=77afa6b4 ecx=002afd48 edx=00000001 esi=001cdaa4 edi=00000000
eip=77bf5e74 esp=001cda5c ebp=001cdacc iopl=0         nv up ei ng nz ac pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000297
ntdll!KiFastSystemCallRet:
77bf5e74 c3              ret

然而,这对我来说不太重要。据我所知,我需要编写命令以获得有用的输出,Visual Studio更好用。

因此,我使用Visual Studio打开它。我可以选择“仅调试本地代码”,但是我看到了很多对聪明人有意义的东西,而我不聪明!我得到了这两个屏幕:

enter image description here

enter image description here

那么,我的问题是:

如何将源代码显示在Visual Studio中?

此外,是否有一种方法可以获取较小的转储文件?即使经过压缩,它似乎也非常大。我不明白为什么不能只有一个比程序占用空间稍微大一点的文件,仍然能够得到带有源代码的良好调试。


你熟悉 Visual Studio 内置的调试器吗?我实际上没有完全阅读你问题的最后部分,但不清楚为什么这对你不起作用。 - Cody Gray
1
说实话,我不熟悉它,这就是为什么我来这里的原因。肯定有一个“加载源”按钮,但我能找到它吗... - niemiro
3个回答

50
Visual Studio 2010可以让你调试崩溃转储文件并逐步执行托管源代码,这是一项非常广告宣传的功能,但需要注意的是:它仅适用于.NET 4.0程序集。以下是操作步骤:
  1. 在另一台电脑上使用任务管理器创建crash dump文件
  2. 在VS2010中打开解决方案
  3. 打开.DMP文件(文件->打开...)
  4. 点击“Debug With Mixed”(只对.NET 4.0可见)
  5. 源代码将打开,并且您将能够检查异常的确切原因和位置
就本地调试而言,Visual Studio与WinDbg相比已不再有用。

如果在生成转储时向本机应用程序注入了DLL并且您想找出DLL崩溃的原因,这是否也适用?当然,该DLL是.NET4+。 - Guapo
1
我也遇到了同样的问题,但是在Visual Studio中我看不到源代码。我正在使用.Net 4.5和VS15。你能否请指导我一些设置,以便在VS中获取转储文件的源代码? - Anchit Pancholi

48
你在这里使用的工具从未被设计用来解决崩溃的托管程序问题。小型转储文件和Windbg是用来查找C或C++编写的代码有什么问题的工具。这些语言的运行时不支持从崩溃的托管程序中获取的重要信息,如带有堆栈跟踪的异常。
minidump大小差异很大是因为"minidump"中的 "mini"。按照设计,它旨在捕获进程的小快照。相关参数是MiniDumpWriteDump函数中的DumpType。这个函数中有非常聪明的代码,可以确定在调试器会话中不太可能使用的进程状态的哪些部分不需要记录。你可以通过提供额外的dump类型标志来覆盖它们。Explorer生成的minidump已经打开了所有这些标志,你会得到整个包裹(kit)和马车(caboodle)。
这对于托管程序实际上非常重要。此minidump创建者使用的启发式算法只适用于非托管代码。仅当在dump中包含整个垃圾回收堆时,调试托管程序dump才能正常工作。是的,那将是一个庞大的dump,minidump不再适用。
你的下一个问题是从minidump数据中获取机器视图。你的屏幕截图显示的是机器码。在这些截图中,你碰巧位于Windows内部,注意堆栈顶部的ntdll.dll。mscorwks.dll条目是CLR。在下面的视图中,应该看到来自你自己代码的堆栈帧。但是,你将看到JIT编译器生成的机器码。而不是你的C#代码。

有一个名为sos.dll的Windbg插件,它扩展了Windbg的命令集,以便检查托管数据。 只需谷歌“sos.dll”即可获得良好的搜索结果。 但是,这仍然远远不及Visual Studio调试器所提供的调试体验。后者非常熟悉托管代码,与Windbg或能够加载小内存转储的VS调试器完全不同。Sos实际上是为了解决CLR错误而设计的。

除了您现在看到的minidump信息页外,在VS2010中并没有什么显着的改进。 它实际上并没有做太多事情。 我怀疑调试器团队已经将此列入待办事项清单,肯定还有一些根本性的问题需要解决。 特别是在minidump格式和创建代码方面。 使用connect.microsoft.com提供反馈,他们会关注并让投票影响其优先级列表。


非常感谢!你教会了我很多东西。我真的非常感激你为我所做的一切。非常感谢你抽出时间来帮助我。我一直在不停地切换“标记为答案”!有这么多精彩的答案(这就是你的实力!)再次非常感谢你! - niemiro
4
@大家:请多点赞以弥补我只能将一个帖子标记为答案的遗憾! - niemiro

5

您应该向调试器提供相关的pdb(程序数据库)文件,以便它加载符号。此外,为了获得更好的视图,请使用Microsoft公共符号服务器。这篇文章包含相关信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接