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 打开它。我可以选择“仅使用 Native 进行调试”,但我得到了很多对像你这样聪明的人有意义的东西,而我并不聪明!我得到这两个屏幕:

在此处输入图像描述

在此处输入图像描述

所以,我的问题:

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

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

4

3 回答 3

49

Visual Studio 2010 允许您调试故障转储文件并逐步执行托管源代码的广为宣传的功能带有一个陷阱:它仅适用于 .NET 4.0 程序集。以下是步骤:

  1. 使用任务管理器在另一台计算机上创建故障转储文件
  2. 在VS2010中打开解决方案
  3. 打开 .DMP 文件(文件->打开...)
  4. 单击Debug With Mixed(这将仅对 .NET 4.0 可见)
  5. 源代码将打开,您将能够检查异常的确切原因和位置

就仅使用本机进行调试而言,Visual Studio 并不比 WinDbg 有用。

于 2011-01-15T11:59:07.587 回答
47

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

minidump 大小如此不同的原因是 minidump 中的 mini。按照设计,它旨在捕获该过程的一个小快照。相关参数是MiniDumpWriteDump 函数中的 DumpType 。这个函数中有非常聪明的代码可以找出进程状态的哪些部分不需要记录,因为您不太可能在调试器会话中使用它。您可以通过提供额外的转储类型标志来覆盖它。Explorer 生成的 minidump 已打开所有这些标志,您将获得整个套件和 caboodle。

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

您的下一个问题是您正在从小型转储数据中获取机器视图的灵魂。您的屏幕截图显示机器代码。在这些镜头中,您恰好位于 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 提供反馈,他们会关注并让投票影响他们的优先级列表。

于 2011-01-15T12:11:52.143 回答
5

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

于 2011-01-15T11:55:09.573 回答