Debugging dump files in Visual Studio
I am using Visual Studio 2010 Professional Edition, and Windows Vista.
Firstly, I have this code. As you can see, it will crash the program!
using System;
namespace Crash
{
class Program
{
static void Main(string[] args)
{
string a = null;
if (a.Length == 12)
{
// ^^ Crash
}
}
}
}
The program will crash on the if statement. Now, I want to find out that it crashed on that if statement.
If I "Start without Debugging" from Visual Studio, Crash.exe crashes. It uses 1,356kb of memory. I get the Vista option of Close Program/Debug. If I choose Debug, I can open a new instance of Visual Studio, and it points me to a NullReferenceException on the if statement. This is good.
Now let me assume that it crashes on another computer, and I get them to give me a Dump File via Task Manager. It is 54,567kb. Why so big! It's vast! Anyway, I am less interested in that (slightly)
If I open that dump with Windbg, I get very little of use to my untrained eye:
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
However, this is of less interest to me. As far as I can tell, I need to write commands in to get useful output, and Visual Studio is better.
So I open it with Visual Studio. I can choose to "Debug with Native Only", but I get lots of things that mean something to clever people like you, and I am not clever! I get these two screens:
So, my question:
How do I show Visual Studio to my source code?
Also, is there a way to get a smaller dump file? It seems ridiculously big, even after compressing. I don't understand why there couldn't be one which is only just a tiny bit bigger than the program's footprint, and still get a nice debugging, with the source code.
Solution 1:
The much advertised feature that Visual Studio 2010 allows you to debug crash dump files and step through the managed source code comes with a gotcha: it works only for .NET 4.0 assemblies. Here are the steps:
- Create a crash dump file on another computer using the Task Manager
- Open the solution in VS2010
- Open the .DMP file (File->Open...)
- Click on
Debug With Mixed
(This will be visible only for .NET 4.0) - Source code will open and you will be able to inspect the exact cause and location of the exception
As far as debugging with native only is concerned Visual Studio is no more useful than WinDbg.
Solution 2:
The tooling you are using here wasn't ever designed to troubleshoot crashing managed programs. Minidumps and Windbg is what you use to find out what's wrong with code written in C or C++. Pretty important tools, these are languages whose runtimes have no support for the kind of goodies you can get out of a crashing managed program. Like an exception with a stack trace.
The reason the minidump sizes are so different is because of the mini in minidump. By design, it was meant to capture a small snapshot of the process. The relevant argument is DumpType in the MiniDumpWriteDump function. There's really clever code in this function that can figure out what parts of the process state don't need to be recorded because you are not likely to use it in the debugger session. Which you can override by providing additional dump type flags. The minidump that Explorer generates has all of those flags turned on, you get the whole kit and caboodle.
Which is actually pretty important for a managed program. The heuristics used by this minidump creator is one that's only appropriate for unmanaged code. Debugging a managed program dump only works well when you include the entire garbage collected heap in the dump. Yes, that will be a large dump, mini doesn't apply anymore.
Your next problem is that you are getting the soul of the machine view from the minidump data. Your screen shots are showing the machine code. You happen to be located inside of Windows in those shots, note how ntdll.dll is on top of the stack. The mscorwks.dll entries are the CLR. Further down, out of view, you ought to see stack frames from your own code. You'll however see the machine code that was generated by the JIT compiler. Not your C# code.
There's a Windbg add-in called sos.dll that extends the command set of Windbg to be able to inspect managed data. Just google "sos.dll" to get good hits. This is however still a looong way away from the kind of debug experience you'll get out of the Visual Studio debugger. Which is intimately aware of managed code, very unlike Windbg or the VS debugger that can load minidumps. Sos was really designed to troubleshoot CLR bugs.
There were no dramatic improvements in VS2010 other than the minidump info page you now see. Which really doesn't do much at all. I suspect the Debugger Team to have this on their todo list, there are surely some fundamental problems to overcome. Particularly in the minidump format and creation code. Use connect.microsoft.com to provide feedback, they pay attention to it and let votes affect their priority list.
Solution 3:
You should be supplying the related pdb (program database) file to the debugger so it can load the symbols. Also to get a better view, use Microsoft Public Symbol server. This article contains information on it.