确定ZwWaitForMultipleObjects正在等待的对象

时间:2013-05-23 11:42:11

标签: windbg

在windbg中查看崩溃转储,我可以看到所有当前线程都停在

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

或单个对象的变体。

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

!do <address>

使用正确的地址 - 但我不知道如何构建正确的地址。我假设我需要从ChildEBP获得一些偏移量?

1 个答案:

答案 0 :(得分:14)

尝试以下步骤:

  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扩展程序查看每个句柄的详细信息,如下所示: !处理1f0 F. F标志将显示有关句柄的更多详细信息,包括其计数和名称(如果有一个与之关联)

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