2

我有一个由于死锁而挂起的 .Net 进程的转储(gui 线程不再响应,我的日志显示某些线程已停止响应)。我已经拍了一张快照,现在正在windbg中查看它,所有线程都在等待最后一个。用 !clrstack -p 查看那个线程的堆栈跟踪,我可以看到它正在尝试获取对 ReaderWriterLock 的写入

我如何知道哪个其他线程持有该锁,以便我可以开始弄清楚死锁是如何发生的?

谢谢

[编辑] .Net1.1 sos.dll 中显然有一个命令 !rwlocks 可以帮助解决这个问题,但 .Net2.0 版本中没有。狩猎继续

4

5 回答 5

1

我不是很确定,但你也许可以使用 !SyncBlk 来查看同步块对象,如果你在没有任何参数的情况下调用它,我认为你应该看到线程拥有的同步块。

如果你有一个同步块死锁,扩展SOSEX可能是你需要的。这个扩展提供了命令 !dlk 来显示哪些线程正在等待哪些锁。但这仅适用于同步块,不会检测到其他同步对象上的死锁,如果您使用 lock() (Monitor.Enter),这对您来说应该不是问题。

于 2008-11-25T18:40:04.770 回答
1

试试sosex和 !dlk

于 2008-12-10T22:03:55.367 回答
1

不久前我在这里发布了一个类似的主题,使用 C# 是否可以测试文件上是否持有锁

我参考了许多文章等,但是等待链遍历 (WCT) 可以帮助您,这有点棘手,但这篇 msdn mag bugslayer文章展示了如何在托管上下文中在 windbg 中使用 WCT。

于 2009-05-19T20:05:09.220 回答
0

到目前为止,最好的方法是查看所有线程堆栈的 !dso,并查看哪些引用了锁。之后的快速检查让我们能够追踪哪些线程持有锁。虽然真的不是一个漂亮或快速的方法......

于 2008-11-26T11:48:04.787 回答
0

提供可追溯性的一种方法是将锁包装到 IDisposable 接口中并替换:

锁(我的锁){...}

使用(新的 DisposeableLock()){ ... }

您可以将构造函数和 Dispose() 方法记录到控制台、log4net 或其他一些机制。这将允许您查看正在锁定的内容以及正在阻止的内容。

于 2008-11-27T02:48:55.810 回答