Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I get the stack traces of all threads in my c# app?

Tags:

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?

like image 898
Drew Shafer Avatar asked Apr 27 '10 18:04

Drew Shafer


People also ask

What does the stack trace contain?

The stack trace, also called a backtrace, consists of a collection of stack records, which store an application's movement during its execution. The stack trace includes information about program subroutines and can be used to debug or troubleshoot and is often used to create log files.

What is thread stack trace?

A stack trace is a user-friendly snapshot of the threads and monitors in a Virtual Machine for the Java platform (Java Virtual Machine or JVM machine). A thread dump shows what every thread in a JVM is doing at a given time and is useful in debugging.

How do I recover stack trace?

You can obtain a stack trace from a thread – by calling the getStackTrace method on that Thread instance. This invocation returns an array of StackTraceElement, from which details about stack frames of the thread can be extracted.


2 Answers

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.

like image 82
adrianbanks Avatar answered Sep 19 '22 03:09

adrianbanks


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.

like image 43
wal Avatar answered Sep 19 '22 03:09

wal