在 Visual Studio 2008 中为 .Net 托管应用程序从 WinDbg 调试 .dmp 文件

Posted

技术标签:

【中文标题】在 Visual Studio 2008 中为 .Net 托管应用程序从 WinDbg 调试 .dmp 文件【英文标题】:Debugging .dmp files from WinDbg in Visual Studio 2008 for .Net managed apps 【发布时间】:2010-11-15 10:34:00 【问题描述】:

我正在尝试查找如何获取 .Net 托管可执行文件的故障转储,然后在 Visual Studio 2008 中打开生成的 .dmp 文件。我想查看在源代码中引发异常的位置,调用堆栈以及栈上函数中变量的值。

为了简化问题,我写了一个会崩溃的小应用:

...

class Program

    static void Main(string[] args)
    

        int a = 2;           //Variable I want to see value for when debugging

        if (!File.Exists(@"C:\Crasher\bin\Debug\file.txt")) //Doesn't exist
            throw new FileNotFoundException();     //Unhandled exception thrown
    

...

我做了一个 DEBUG 构建并从 Visual Studio 外部运行它。在 windbg 中,我单击“附加到进程”并选择了我的应用程序。然后我在windbg命令窗口中输入:

          .dump /ma C:\crasher\bin\debug\dump.dmp

然后我在 Visual Studio 中打开了 .dmp 文件。我去了工具->选项->调试->符号并添加了以下内容:

          http://msdl.microsoft.com/download/symbols  (saved to local folder)

这为我提供了模块窗口中列出的所有 DLL 的符号(例如 Kernel32.dll、gdi32.dll - 我认为所有列出的都是本机的),但 mscorlib.ni.dll 除外。 Microsoft Symbol Server 为我提供了 mscorlib.dll 但不是 mscorlib.ni.dll 的符号构建和 .pdb。

当我尝试为我的 .exe 本身加载 .pdb 时,它告诉我它与应用程序不匹配。我认为这是因为 .exe 是托管的,并且我们还没有它下面的所有本机代码的符号 - 即,如果我可以获得 mscorlib.ni.dll 的符号构建和 pdb,这将起作用。

这个推理正确吗?我还缺少其他东西吗?

无论哪种方式,为什么 mscorlib.ni.dll 在 Microsoft 符号服务器上不可用,我在哪里可以获得符号信息,还有什么我应该知道的通过 Visual Studio 中的故障转储调试托管代码。

非常感谢 - 任何帮助将不胜感激。

菲尔·惠廷顿

【问题讨论】:

不是JIT编译代码的dmp吗?这行得通吗? 我认为这是不可能的。 为什么还要使用 Visual Studio? WinDBG 要强大得多。 在 VS2008 中无法做到这一点。使用 VS 2010(我认为是终极版)你当然可以做到这一点。你最好的选择是使用 WinDbg。查看blogs.msdn.com/b/tess/archive/2006/05/18/… 这并不容易,但如果你能习惯使用 WinDbg,那么你的武器库中就会拥有一个非常强大的工具。 【参考方案1】:

正如 Jason Evans 在他的评论中所说,这在 VS2008 中不受支持,但您可以在 WinDbg 中做到这一点。

为此类崩溃获取正确转储的最简单方法是使用 adplus(包含在 Windows 调试工具中)。有多种选择,但要根据进程名称获取故障转储,您可以这样做

>adplus -crash -o c:\dumpdirectory -pn app.exe

这会给你两个转储。一个用于第一次机会例外,一个用于第二次。在这种情况下,它们实际上是相同的,但对于更实际的情况,第一次机会异常转储将向您显示异常被抛出时(即在任何异常处理发生之前)的应用程序状态。第二次机会异常转储将向您显示未处理异常的状态。

要获取异常,请打开故障转储并通过键入 .loadby sos mscorwks 加载 SOS。

然后使用!pe 命令在当前线程上打印异常(在这种情况下将是故障线程)。它看起来像这样:

0:000> !pe
Exception object: 024a5114
Exception type: System.IO.FileNotFoundException
Message: Unable to find the specified file.
InnerException: <none>
StackTrace (generated):
    SP       IP       Function
    0020F0F0 005100D6 TestBench!TestBench.Program.Main()+0x66

StackTraceString: <none>
HResult: 80070002

要列出局部变量a,请使用!clrstack -l,但请记住,由于优化,局部变量很少在发布模式构建中可用。

0:000> !clrstack -l
OS Thread Id: 0x1a50 (0)
ESP       EIP     
0020f04c 7571b727 [HelperMethodFrame: 0020f04c] 
0020f0f0 005100d6 TestBench.Program.Main()
    LOCALS:
        0x0020f0fc = 0x00000002  <--- the value of a
        0x0020f0f8 = 0x00000000

0020f328 51141b5c [GCFrame: 0020f328] 

【讨论】:

Brian,非常感谢你 - 我还没有尝试过,但想回复一下。如果有任何其他查询出现,将进一步发布:) 再次感谢。私服 @Phil 不客气。请务必查看带有 WinDbg/SOS 标记的问题,因为如果您要学习 WinDbg,其中一些可能会有所帮助。

以上是关于在 Visual Studio 2008 中为 .Net 托管应用程序从 WinDbg 调试 .dmp 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Visual Studio 2008 中打开使用 Visual Studio 2005 创建的 rdl?

如何在 Visual Studio 2008 或 Visual Studio 2010 中设置 JavaScript 断点

我可以在 Visual Studio 2008 中使用 Visual Studio 6 编译的 C++ 静态库吗?

Visual Studio 2010 显示旧的 Visual Studio 2008“添加引用”对话框

Visual Studio 2012 未能检测到 Visual Studio 2008 构建工具

如何在visual studio2008中创建,编译和运行C++程序,