8

如何在windbg中找出哪个线程是我的事件句柄的所有者:

我在跑

!handle 00003aec f

并得到

Handle 00003aec
  Type          Event
  Attributes    0
  GrantedAccess 0x1f0003:
     Delete,ReadControl,WriteDac,WriteOwner,Synch
     QueryState,ModifyState
  HandleCount   2
  PointerCount  4
  Name          <none>
  No object specific information available

回来,因为没有名字我还没想出如何让所有者证明我的线程正在等待哪个线程

[编辑] 我必须处理转储,因为需要在用户机器上重新启动原始进程,因此无法调试实时会话

到目前为止我发现的关于这个主题的最佳讨论是在这个博客上,但不幸的是我们最终使用了不同的锁定方法(我最终使用了 WaitForMultipleObjectsEx,描述是针对 WaitForSingleObject),而且他似乎可以访问实时进程

我的线程的堆栈跟踪(在某事上被阻塞并且我正在寻找当前所有者的线程)是:

0:045> k9
ChildEBP RetAddr 
1130e050 7c90e9ab ntdll!KiFastSystemCallRet
1130e054 7c8094e2 ntdll!ZwWaitForMultipleObjects+0xc
1130e0f0 79ed98fd kernel32!WaitForMultipleObjectsEx+0x12c
1130e158 79ed9889 mscorwks!WaitForMultipleObjectsEx_SO_TOLERANT+0x6f
1130e178 79ed9808 mscorwks!Thread::DoAppropriateAptStateWait+0x3c
1130e1fc 79ed96c4 mscorwks!Thread::DoAppropriateWaitWorker+0x13c
1130e24c 79ed9a62 mscorwks!Thread::DoAppropriateWait+0x40
1130e2a8 79e78944 mscorwks!CLREvent::WaitEx+0xf7
1130e2bc 7a162d84 mscorwks!CLREvent::Wait+0x17
1130e33c 7a02fd94 mscorwks!CRWLock::RWWaitForSingleObject+0x6d
1130e364 79ebd3af mscorwks!CRWLock::StaticAcquireWriterLock+0x12e
1130e410 00f24557 mscorwks!CRWLock::StaticAcquireWriterLockPublic+0xc9
4

4 回答 4

2

查看调用堆栈,似乎有问题的堆栈正在使用 ReaderWriterLock 锁定机制。

1130e410 00f24557 mscorwks!CRWLock::StaticAcquireWriterLockPublic+0xc9

切换到线程 9 并使用sos.dll运行!dso转储出托管的 ReaderWriterLock 对象。然后在 ReaderWriterLock 对象上运行 !do。我相信您可以查询一个拥有的线程字段。我会测试一下看看。

确定这一点的老派方法是运行~*e !clrstack并检查正在等待读写器锁的所有托管线程,然后查看是否可以找到进入相同函数但通过锁的线程(即不同的偏移量)

谢谢,亚伦

注意:不确定是否有链接帖子的方法,但这与
如何在 Windbg 中找到我的 ReaderWriterLock 的锁持有者(阅读器)非常相似

于 2009-02-22T00:23:35.350 回答
1

使用!htrace命令获取线程 ID。您必须首先(可能在程序开始时)使用!htrace -enable.

0:001> !htrace 00003aec
--------------------------------------
句柄 = 0x00003aec - 打开
线程 ID = 0x00000b48,进程 ID = 0x000011e8

...

上面的输出是虚构的,对于您的系统会有所不同。但它会为您提供所需的信息——线程 ID(在我的示例中为 0x00000b48)。

我必须处理转储,因为需要在用户机器上重新启动原始进程,因此无法调试实时会话。

我不是 100% 确定,但我认为这会奏效:

  1. 附加到进程并运行!htrace -enable
  2. 与进程分离qd。可执行文件将继续。
  3. 您现在可以获取转储文件并使用上述命令 - 我认为您将获得所描述的结果。
于 2009-08-19T16:24:38.973 回答
0

您可以从内核转储中挖掘出来。

现在,就内核调试而言,来自 sysinternals 的 livekd 应该就足够了,但不幸的是,它只能在正在运行的系统上使用。

还有一个内核模式内存获取工具,可用于(代替windbg)进行转储以供以后检查。

否则,启用句柄跟踪(!htrace -enable)和(如果代码对特定线程唯一),可以从堆栈跟踪中得出句柄所有权。

于 2009-01-22T17:43:48.207 回答
0

这是我找到的明确答案。从来没有试过自己。不过,您需要进行实时调试才能确定所有者。但这很快。 http://weblogs.thinktecture.com/ingo/2006/08/who-is-blocking-that-mutex---fun-with-windbg-cdb-and-kd.html

于 2010-11-23T11:34:19.533 回答