【问题标题】:Debugging dump files in Visual Studio在 Visual Studio 中调试转储文件
【发布时间】:2011-01-15 11:23:38
【问题描述】:

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

那么,我的问题:

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

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

【问题讨论】:

  • 您熟悉 Visual Studio 中内置的调试器吗?我实际上并没有一直读到你问题的底部,但不清楚为什么这对你不起作用。
  • 老实说,我对它并不熟悉,这就是我来这里的原因。某处必须有一个“加载源”按钮,但我能找到它吗...

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


【解决方案1】:

Visual Studio 2010 允许您调试故障转储文件并逐步检查托管源代码的广为宣传的功能带有一个陷阱:它可以工作only for .NET 4.0 assemblies。步骤如下:

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

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

【讨论】:

  • 如果在生成转储时将 dll 注入本机应用程序并且您想找出 dll 崩溃的原因,这是否也有效?当然 dll 是 .net4+。
  • 我也面临同样的问题,但我在 Visual Studio 中看不到源代码。我正在使用 Net 4.5 和 VS15。您能否指导我进行一些设置以在 VS 中获取带有转储文件的源代码
【解决方案2】:

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

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

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

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

【讨论】:

  • 非常感谢!你教会了我很多。我真的非常感谢你为我所做的一切。非常感谢您花时间帮助我。我一直在切换“标记为答案”!这么多奇妙的答案(嗯,对你来说就是这样!)再次感谢你!
  • @Everyone:请给这么多点赞来弥补,我只能将一个帖子标记为答案!
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    相关资源
    最近更新 更多