我可以获得 C# 应用程序中所有线程的堆栈跟踪吗?

发布于 2024-08-31 04:35:55 字数 195 浏览 2 评论 0原文

我正在工作中调试一个大型应用程序中的一个明显的并发问题。该错误仅在运行许多(12+)小时后在某些性能较低的计算机上出现,并且我从未在调试器中重现它。正因为如此,我的调试工具基本上仅限于分析日志文件。

C# 可以轻松获取抛出异常的线程的堆栈跟踪,但我还想获取抛出异常时当前在我的 AppDomain 中执行的所有其他线程的堆栈跟踪。

这可能吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谈下烟灰 2024-09-07 04:35:55

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

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

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.

南渊 2024-09-07 04:35:55

我建议在异常发生时转储进程。在记录异常的同一位置,调用 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} -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

打印所有托管线程的调用堆栈。如果您需要更多帮助,请回发 Windbg 或 google 获取教程。

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.

我早已燃尽 2024-09-07 04:35:55

我自己还没有尝试过,但它可能有用 http://www.debuginspector.com/

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文