如何调试死锁?

时间:2009-07-18 12:10:22

标签: c# multithreading deadlock

除此之外,我不知道我现在是否可以重现它(我已经使用这个特定的应用程序一两个星期没有问题),假设我在VS中运行我的应用程序调试器,如何在发生死锁后调试死锁?如果我暂停程序并因此看到不同的线程发生在哪里,我认为我可能能够获得调用堆栈,但是单击暂停只会使Visual Studio陷入僵局,直到我杀死我的应用程序。

除了浏览我的源代码树以寻找潜在问题之外,还有其他方法吗?一旦出现问题,是否有办法获得调用堆栈以查看问题所在?还有其他可能有用的工具/提示/技巧吗?

4 个答案:

答案 0 :(得分:9)

你所做的是正确的方法。如果Visual Studio也死锁,那么偶尔会发生这种情况。这只是运气不好,除非还有其他一些问题。

您无需在调试器中运行该应用程序即可进行调试。正常运行应用程序,如果发生死锁,您可以稍后附加VS. Ctrl + Alt + P ,选择流程,选择调试器类型,然后点击附加。使用一组不同的调试器类型可以降低VS崩溃的风险(特别是如果您不调试本机代码)

死锁涉及2个或更多线程。您可能知道第一个(可能是您的UI线程),因为您注意到应用程序中的死锁。现在你只需要找到另一个。有了架构知识,它应该很容易找到(例如,其他线程使用相同的锁,与UI交互等)

如果VS 不起作用,您可以随时使用 windbg 。在此下载:http://www.microsoft.com/whdc/devtools/debugging/default.mspx

答案 1 :(得分:3)

我会按以下顺序尝试不同的方法:

- 首先,检查代码以查找线程安全违规,确保您的关键区域不会调用其他函数,而这些函数又会尝试锁定关键区域。

- 使用你可以用来查看线程活动的任何工具,我使用内部perl脚本来解析我们制作的操作系统日志,并绘制所有上下文切换图并显示线程被抢先的时间。

- 如果找不到好的工具,请执行一些日志记录以查看在发生死锁之前运行的最后一个线程。这将为您提供可能导致问题的位置的线索,如果锁定机制具有唯一名称(例如,如果对象具有自己的线程,创建专用信号量或互斥锁以管理该线程),则会有所帮助。

我希望这会有所帮助。祝你好运!

答案 2 :(得分:0)

就像任何地方一样,没有“银弹”工具可以捕获所有的死锁。所有这些都是关于不同线程获取资源的顺序,因此您的工作就是找出违反订单的位置。通常Visual Studio或其他调试器将提供堆栈跟踪,您将能够找出差异的位置。 DevPartner Studio确实提供了死锁分析,但上次我检查过的误报太多了。一些静态分析工具也会发现一些潜在的死锁。

除此之外,它有助于使架构直接执行资源获取订单。例如,分层有助于确保在较低级别锁定之前采取上级锁定,但要注意回调。

答案 3 :(得分:-1)

您可以使用不同的程序,如英特尔(R)Parallel Inspector:
http://software.intel.com/en-us/intel-parallel-inspector/

此类程序可以向您显示代码中存在潜在死锁的位置。但是您应该为此付费,或仅使用评估期。不知道是否有这样的免费工具。