在Visual Studio中调试转储文件

时间:2011-01-15 11:23:38

标签: c# debugging visual-studio-2010 crash-dumps

我正在使用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的内存。我得到了Close Program / Debug的Vista选项。如果我选择Debug,我可以打开一个新的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打开它。我可以选择“仅使用Native进行调试”,但是我得到的很多东西对于像你这样聪明的人来说意味着什么,而且我并不聪明!我得到这两个屏幕:

enter image description here

enter image description here

所以,我的问题:

如何向我的源代码显示Visual Studio?

另外,有没有办法获得更小的转储文件?即使在压缩之后,它看起来也非常大。我不明白为什么不能只有一个比程序占用空间大一点的东西,并且仍然可以通过源代码得到一个很好的调试。

3 个答案:

答案 0 :(得分:44)

Visual Studio 2010允许您调试故障转储文件并逐步执行托管源代码的广告功能附带了一个问题:它可以正常运行only for .NET 4.0 assemblies。以下是步骤:

  1. 使用任务管理器在另一台计算机上创建故障转储文件
  2. 在VS2010中打开解决方案
  3. 打开.DMP文件(文件 - >打开...)
  4. 点击Debug With Mixed(这仅适用于.NET 4.0)
  5. 将打开源代码,您将能够检查异常的确切原因和位置
  6. 就仅使用native进行调试而言,Visual Studio并不比WinDbg更有用。

答案 1 :(得分:41)

您在此处使用的工具并非旨在解决崩溃的托管程序问题。使用Minidumps和Windbg来查找用C或C ++编写的代码有什么问题。非常重要的工具,这些语言的运行时不支持您可以从崩溃的托管程序中获得的那种好东西。就像堆栈跟踪的异常一样。

minidump尺寸如此不同的原因是因为minidump中的迷你。按照设计,它旨在捕获过程的一个小快照。相关参数是MiniDumpWriteDump function中的DumpType。在这个函数中有一些非常聪明的代码可以找出不需要记录过程状态的哪些部分,因为你不太可能在调试器会话中使用它。您可以通过提供其他转储类型标志来覆盖。资源管理器生成的minidump打开了所有这些标志,你可以得到整个套件和cabo​​odle。

对于托管程序而言,这实际上非常重要。这个minidump创建者使用的启发式算法只适用于非托管代码。只有在转储中包含整个垃圾回收堆时,才能调试托管程序转储。是的,这将是一个大型转储,迷你不再适用。

您的下一个问题是您从minidump数据中获得了机器视图的灵魂。您的屏幕截图显示机器代码。你碰巧在这些镜头中位于Windows内部,注意ntdll.dll是如何在堆栈顶部的。 mscorwks.dll条目是CLR。再往下看,你应该从你自己的代码中看到堆栈帧。但是,您将看到由JIT编译器生成的机器代码。不是你的C#代码。

有一个名为sos.dll的Windbg加载项,它扩展了Windbg的命令集,以便能够检查托管数据。只需谷歌“sos.dll”获得良好的点击率。然而,这仍然是远离Visual Studio调试器的调试体验的 looong 方式。这是密切关注托管代码的,非常不像Windbg或可以加载minidump的VS调试器。 Sos真的是为解决CLR错误而设计的。

除了您现在看到的minidump信息页面之外,VS2010没有任何显着的改进。这真的没什么用。我怀疑Debugger团队在他们的待办事项清单上有这个,肯定有一些基本问题需要克服。特别是在minidump格式和创建代码中。使用connect.microsoft.com提供反馈,他们会关注它并让投票影响他们的优先级列表。

答案 2 :(得分:5)

您应该将相关的pdb(程序数据库)文件提供给调试器,以便它可以加载符号。另外,要获得更好的视图,请使用Microsoft Public Symbol服务器。 This article包含有关它的信息。