views:

243

answers:

3

I'm debugging an apparent concurrency issue in a largish app that I hack on at work. The bug in question only manifests on certain lower-performance machines after running for many (12+) hours, and I have never reproduced it in the debugger. Because of this, my debugging tools are basically limited to analyzing log files.

C# makes it easy to get the stack trace of the thread throwing the exception, but I'd like to additionally get the stack traces of every other thread currently executing in my AppDomain at the time the exception was thrown.

Is this possible?

+3  A: 

There is a tool on CodePlex called Managed Stack Explorer (that I believe originated from Microsoft). It uses the debugging and profiling API to capture the stack traces of the threads in a running .Net application, without the need to modify the application.

You could run your application until you experience the issue, then analyse it using this tool to capture the current stack traces of all running threads. The benefit of this approach is that you leave your application unmodified (instrumenting it may change its behaviour), and the tool is free.

adrianbanks
This looks like the best solution. It would certainly be nice if the framework supported it natively within the language, though...
Drew Shafer
A: 

I haven´t tried this my self but it might be of use http://www.debuginspector.com/

Jens Granlund
A: 

I suggest taking a dump of the process when the exception occurs. In the same place where you are logging the exception call the MakeDumpFile() method as below.

This assumes you have Debugging Tools For Windows installed on the problematic machine.

private static void MakeDumpFile()
    {            
        int pid = Process.GetCurrentProcess().Id;
        Console.WriteLine("Creating dump for pid " + pid);

        //path to adplus executable; ensure you have Debugging tools installed;
        string program = @"C:\Program Files (x86)\Debugging Tools for Windows (x86)\adplus.exe";

        //args for adplus; ensure the crashdump folder exists!
        string args = string.Format(@"-hang -p {0} -o c:\crashdump", pid);

        var startInfo = new ProcessStartInfo(program, args);
        startInfo.UseShellExecute = false;
        startInfo.ErrorDialog = false;
        startInfo.CreateNoWindow = true;
        startInfo.RedirectStandardOutput = true;

        var process = Process.Start(startInfo);
        Console.WriteLine("The following is output from adplus");
        Console.WriteLine(process.StandardOutput.ReadToEnd());
        Console.WriteLine("Finished creating dump.");
    }

Navigate to the dump dir and you should see a new folder with a file in it named FULLDUMP_something_.dmp.

If you are on .NET4 you can simply drag this into VS2010 and check out all the threads or use parallel threads to see what is going on (this is awesome!)

If on NET3.5 or earlier you will need to use windbg to analyse. Use the following command

~*e !clrstack

to print the callstack of all managed threads. If you need more help getting windbg going post back or google for a tutorial.

wal