【问题标题】:Determining which objects ZwWaitForMultipleObjects is waiting on确定 ZwWaitForMultipleObjects 正在等待哪些对象
【发布时间】:2013-05-23 11:42:11
【问题描述】:

查看windbg中的故障转储,我可以看到所有当前线程都停止在

> ~2k
ChildEBP RetAddr  
00d2fcc8 7d4e27dc ntdll_7d600000!ZwWaitForMultipleObjects+0x15

或相同的 SingleObject 变体。

由于要等待的对象的句柄被传递给 ZwWaitForMultipleObjects,我假设我可以使用变体来计算出它正在使用的对象

!do <address>

使用正确的地址 -- 但我不知道如何构造正确的地址。我假设我需要从 ChildEBP 中获得一些补偿?

【问题讨论】:

  • !do 用于托管对象 (.NET),但 ZwWFMO 很可能正在等待本机句柄。使用~2kb 获得一个有据可查的 Win32 框架,进一步提升堆栈(希望是 WaitForMultipleObjects)及其前三个参数。您必须取消第二个参数才能获得句柄。当您获得句柄值时,请使用!handle &lt;handle&gt; f 获取有关特定句柄的信息。如果您在挖掘句柄值方面需要帮助,请将输出发布到 ~2kb

标签: windbg


【解决方案1】:

试试这些步骤:

  1. 使用“~2s”命令将上下文切换到线程#2(这个步骤可以说是多余的,但我发现在正确的线程上下文中操作更容易)

  2. 使用“kb”命令显示线程的调用堆栈,包括每个函数的前三个参数。你会得到类似的东西:

    ChildEBP RetAddr Args to Child 0dc7fa30 768b0962 00000004 0dc7fa80 00000001 ntdll!ZwWaitForMultipleObjects+0x15 0dc7facc 73c61339 0dc7fa80 0dc7fb14 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x100
  3. 以上面的调用栈为例,可以看到传递给ZwWaitForMultipleObjects的句柄数是4(第一个参数的值)。句柄数组的地址是第二个参数。在上面的例子中,地址是 0dc7fa80

  4. 使用“dd”命令显示句柄数组的内容。在上述调用堆栈的情况下,使用“dd 0dc7fa80”,它会给出如下内容:

    0dc7fa80 000001f0 000001f8 0000020c 000001ec 0dc7fa90 73a53c1b 00000000 0d462f70 00000001 0dc7faa0 0cf7afe0 00000003 0dc7fac8 00000004

    假设这是一个 32 位进程,句柄是前四个单独的 DWORD:“1f0”、“1f8”、“20c”和“1ec”。

  5. 您可以使用“!handle”WinDbg 扩展来查看每个句柄的详细信息,如下所示: !handle 1f0 F F 标志将显示有关句柄的更多详细信息,包括其计数和名称(如果有关联的话)

如果您怀疑句柄是从托管代码传入的,则需要加载 SOS 或 PSSCOR 并使用 !ClrStack 命令显示托管调用堆栈详细信息。

【讨论】:

  • 非常好,感谢 Aeham(以及 Marc 的评论)。太完美了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-12
  • 2015-04-05
  • 2012-11-13
相关资源
最近更新 更多