如何在windbg中找到我的ReaderWriterLock的锁持有者(读者)
我有一个因死锁而挂起的 .Net 进程的转储(gui 线程不再响应,我的日志显示某些线程已停止响应)。 我已经拍摄了一张快照,现在正在 Windbg 中查看它,除了一个线程之外的所有线程都在等待最后一个线程。 使用 !clrstack -p 查看一个线程的堆栈跟踪,我可以看到它正在尝试获取 ReaderWriterLock 上的写入。
如何判断哪个其他线程持有该锁,以便我可以开始弄清楚死锁是如何发生的?
谢谢
[编辑] 显然 .Net1.1 sos.dll 中有一个命令 !rwlocks 可以帮助解决此问题,但 .Net2.0 版本中没有该命令。 狩猎仍在继续
I've got a dump of a .Net process that has hung due to a deadlock (the gui thread is no longer responding, and my logs show that some threads have stopped responding). I have taken a snapshot and am now looking through it in windbg, and all threads bar one are waiting for the last one. Looking at that one thread's stacktrace with !clrstack -p I can see that it is trying to aquire a write on a ReaderWriterLock
How do I tell which other thread holds that lock so I can start figuring out how the deadlock happened?
thanks
[edit] apparently there was a command !rwlocks in the .Net1.1 sos.dll to help with this, but it isn't there in the .Net2.0 version. The hunt continues
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我不太确定,但您也许可以使用 !SyncBlk 来查看同步块对象,如果您在没有任何参数的情况下调用它,我认为您应该看到线程拥有的同步块。
如果您遇到同步块死锁,则扩展 SOSEX 可能正是您所需要的。 此扩展提供了命令 !dlk,该命令显示哪些线程正在等待哪些锁。 但这仅适用于同步块,不会检测到其他同步对象上的死锁,如果您使用 lock() (Monitor.Enter),这对您来说应该不是问题。
I'm not absolutely sure but you might be able to use !SyncBlk to look at the sync block objects, if you invoke it without any arguments I think you should see the sync blocks that are owned by a thread.
If you have a sync block deadlock, the extension SOSEX might be what you need. This extension offers the command !dlk that shows which threads are waiting for which locks. This only works for sync blocks though, deadlocks on other sync objects will not be detected, if you are using lock() (Monitor.Enter) this should not be a problem for you.
尝试 sosex 和 !dlk
Try sosex and !dlk
我不久前在这里发布了一个类似的主题,使用C#是否可以测试文件是否持有锁
我引用了很多文章等,但是等待链遍历(WCT)可以帮助你,这有点敏感,但是这篇 msdn mag bugslayer 文章展示了如何使用托管上下文中 Windbg 中的 WCT。
I posted a simular topic a while back here, Using C# is it possible to test if a lock is held on a file
I referenced a number of articles and such, but wait chain traversial (WCT) can help you, it's somewhat touchy but this msdn mag bugslayer article show's how to use WCT in windbg in a managed context.
到目前为止,最好的方法是查看所有线程堆栈的 !dso,并查看哪些线程堆栈引用了锁。 之后的快速检查让我们能够追踪哪些线程持有锁。 但确实不是一个漂亮或快速的方法......
So far the best approach is to look at the !dso for all thread stacks, and see which ones reference the lock. A quick check after that has alles us to track down which threads hold locks. Really not a pretty or quick way though...
提供可追溯性的一种方法是将锁包装到 IDisposable 接口中,并将:
lock( mylock) { ... }
替换为
using( new DisposeableLock() ) { ... }
您可以记录构造函数和 Dispose() 方法要么到控制台,要么log4net,或者一些其他机制。 这将使您能够看到什么被锁定以及什么被阻塞。
An approach that would provide traceability is to wrap your locks into an IDisposable interface and replace:
lock( mylock) { ... }
with
using( new DisposeableLock() ) { ... }
You can log the constructor and Dispose() methods either to the console, or log4net, or some other mechanism. This will allow you to see what is being lock and what is blocking on what.