【问题标题】:How to debug a deadlock?如何调试死锁?
【发布时间】:2009-07-18 12:10:21
【问题描述】:

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

除了浏览我的源代码树来查找潜在问题之外,还有其他方法吗?一旦问题发生,有没有办法在调用堆栈中查看问题所在?任何其他可能有帮助的工具/提示/技巧?

【问题讨论】:

    标签: c# multithreading deadlock


    【解决方案1】:

    你做的是正确的方法。如果 Visual Studio 也死锁,这种情况不时发生。这只是运气不好,除非有其他问题。

    您不必为了调试它而在调试器中运行应用程序。正常运行应用程序,如果发生死锁,可以稍后附加VS。 Ctrl+Alt+P,选择进程,选择调试器类型,点击attach。使用一组不同的调试器类型可能会降低 VS 崩溃的风险(尤其是在您不调试本机代码的情况下)

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

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

    【讨论】:

    • 链接失效
    • 如果你的死锁一打开工具就消失了,你可能需要修改你的程序来帮忙。你可以做的是在你的程序中启动另一个线程,它唯一的工作就是找出死锁何时发生,然后抛出异常或调用调试器中断,以便保留死锁状态供你查看。
    【解决方案2】:

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

    • 首先,检查代码以查找违反线程安全的情况,确保您的关键区域不会调用其他会反过来尝试锁定关键区域的函数。

    • 使用任何你可以得到的工具来可视化线程活动,我使用内部 perl 脚本来解析我们制作的操作系统日志并绘制所有上下文切换并显示线程何时被抢占.

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 它似乎也只适用于 C/C++(我认为是非托管的,因为据我所知没有托管 C)。
      【解决方案4】:

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

      除此之外,它还有助于让架构直接执行资源获取顺序。例如,分层有助于确保在较低级别的锁定之前获取较高级别的锁定,但要注意回调。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多