我可以在c#app中获取所有线程的堆栈跟踪吗?

我正在调试一个明显的并发问题,这个问题是我在工作中遇到的一个大问题。 有问题的错误仅在运行了许多(12+)小时后出现在某些性能较低的机器上,我从未在调试器中重现它。 因此,我的调试工具基本上只限于分析日志文件。

C#可以很容易地获得抛出exception的线程的堆栈跟踪,但是我还想在抛出exception时另外获取当前在我的AppDomain中执行的每个其他线程的堆栈跟踪。

这可能吗?

CodePlex上有一个名为Managed Stack Explorer的工具(我认为它来自Microsoft)。 它使用调试和分析API来捕获正在运行的.Net应用程序中的线程的堆栈跟踪,而无需修改应用程序。

您可以在遇到问题之前运行应用程序,然后使用此工具对其进行分析,以捕获所有正在运行的线程的当前堆栈跟踪。 这种方法的好处是您可以不修改应用程序(检测它可能会改变其行为),并且该工具是免费的。

我建议在exception发生时转储进程。 在您记录exception的同一位置,调用MakeDumpFile()方法,如下所示。

假设您在有问题的计算机上安装了Windows调试工具 。

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} -oc:\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."); } 

导航到转储目录,您应该看到一个新文件夹,其中包含一个名为FULLDUMP_something_.dmp的文件。

如果您使用的是.NET4,只需将其拖入VS2010并查看所有线程或使用并行线程查看发生了什么(这太棒了!)

如果在NET3.5或更早版本,您将需要使用windbg进行分析。 使用以下命令

〜* e!clrstack

打印所有托管线程的callstack。 如果您需要更多帮助,请将windbg发回或谷歌获取教程。

我没试过这个我的自己,但它可能是有用的http://www.debuginspector.com/