我正在调试一个明显的并发问题,这个问题是我在工作中遇到的一个大问题。有问题的错误仅在运行了许多(12+)小时后出现在某些性能较低的机器上,我从未在调试器中重现它。因此,我的调试工具基本上只限于分析日志文件。
C#可以很容易地获得抛出异常的线程的堆栈跟踪,但是我还想在抛出异常时另外获取当前在我的AppDomain中执行的每个其他线程的堆栈跟踪。
这可能吗?
答案 0 :(得分:6)
CodePlex上有一个名为Managed Stack Explorer的工具(我认为它起源于微软)。它使用调试和分析API来捕获正在运行的.Net应用程序中的线程的堆栈跟踪,而无需修改应用程序。
您可以在遇到问题之前运行应用程序,然后使用此工具对其进行分析,以捕获所有正在运行的线程的当前堆栈跟踪。这种方法的好处是您可以不修改应用程序(检测它可能会改变其行为),并且该工具是免费的。
答案 1 :(得分:5)
我建议在发生异常时转储进程。在您记录异常的同一个地方,调用MakeDumpFile()方法,如下所示。
这假设您在有问题的计算机上安装了 Debugging Tools For 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} -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.");
}
导航到转储目录,你会看到一个新文件夹,里面有一个名为FULLDUMP_something_.dmp的文件。
如果您使用的是.NET4,只需将其拖入VS2010并查看所有线程或使用并行线程查看发生了什么(这太棒了!)
如果在NET3.5或更早版本中,您将需要使用windbg进行分析。使用以下命令
〜* e!clrstack
打印所有托管线程的callstack。如果您需要更多帮助,请将windbg发回,或者谷歌获取教程。
答案 2 :(得分:1)
我没有试过这个我自己,但它可能有用http://www.debuginspector.com/