.netcallstackminidump

Why do minidumps only sometimes have call stacks, for the same process?


Recently we had a hang in production. I used ProcessExplorer to Debug it, saved a minidump in cdb and analyzed it in VS2015. I could see the clr call stack on the main thread with symbols from our code.

Wanting to learn a bit more I created a simple program that would hang (with a bit of a call stack), as follows (built in Release, with source moved after build):

public class Program
{
    public static void Main(string[] args)
    {
        new Program().Run();
    }

    public void Run()
    {
        DoThing();
    }

    public void DoThing()
    {
        Task t = new Task(() =>
            {
                while (true)
                {
                }
            }
        );

        t.RunSynchronously();
    }
}

I subsequently created dump files in three ways:

  1. via task manager
  2. attaching with cdb and .dump /ma
  3. attaching to VS2015, breaking and Saving Dump File

All dumps are very similar in size. When I open these in a new VS2015 session, only the last method shows me the clr call stack for the main thread. Why is this? I don't see the call stack at the point I save the dump in VS, but I do when I re-open the dump file.

How can I guarantee I can see clr call stack when creating a dump in production (when VS isn't available). Also why did I get a clr call stack when I first created the dump file in production using ProcessExplorer and cdb?

UPDATE:
I've checked for strings in the dump files and they all contain values as follows:
< DoThing>b__2_0
DoThing
DoThing>b__2_0

My problem is that minidumps created by Task Manager or cdb have main thread stacks such as:

ntdll.dll!778214d1()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
mscorlib.ni.dll!7279bbc0() 

Whereas ones created by visual studio have main thread stacks like:

DumpDiag.exe!DumpDiag.Program.DoThing.AnonymousMethod__2_0()
mscorlib.dll!System.Threading.Tasks.Task.InnerInvoke()
mscorlib.dll!System.Threading.Tasks.Task.Execute()

Solution

  • This turned out to be because my .net process was 32 bit, but the minidumps I captured with cdb and Task Manager were 64 bit. I was incorrectly using the x64 version of cdb, and the (default) 64 bit Task Manager which captures a 64 bit dump.

    I created separate 32 and 64 bit versions of the test process above, and captured minidumps with the relevant version of cdb, the relevant version of Task Manager, and by attaching with Visual Studio. All dumps showed the clr call stack correctly after this.

    More here: https://blogs.msdn.microsoft.com/tess/2010/09/29/capturing-memory-dumps-for-32-bit-processes-on-an-x64-machine/