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:
- via task manager
- attaching with cdb and .dump /ma
- 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()