在windbg中查看崩溃转储,我可以看到所有当前线程都停在
> ~2k
ChildEBP RetAddr
00d2fcc8 7d4e27dc ntdll_7d600000!ZwWaitForMultipleObjects+0x15
或单个对象的变体。
由于要等待的对象的句柄被传递给ZwWaitForMultipleObjects,我假设我可以找出它使用的变体
!do <address>
使用正确的地址 - 但我不知道如何构建正确的地址。我假设我需要从ChildEBP获得一些偏移量?
答案 0 :(得分:14)
尝试以下步骤:
使用“~2s”命令将上下文切换到线程#2(这一步可以说是多余的,但我发现在正确的线程上下文中操作更容易)
使用“kb”命令显示线程的调用堆栈,包括每个函数的前三个参数。你会得到类似的东西:
ChildEBP RetAddr Args to Child 0dc7fa30 768b0962 00000004 0dc7fa80 00000001 ntdll!ZwWaitForMultipleObjects+0x15 0dc7facc 73c61339 0dc7fa80 0dc7fb14 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x100
以上面的调用堆栈为例,您可以看到传递给ZwWaitForMultipleObjects的句柄数是4(第一个参数的值)。句柄数组的地址是第二个参数。在上面的示例中,地址为0dc7fa80
使用“dd”命令显示句柄数组的内容。在上述调用堆栈的情况下,使用“dd 0dc7fa80”,它将提供如下内容:
0dc7fa80 000001f0 000001f8 0000020c 000001ec 0dc7fa90 73a53c1b 00000000 0d462f70 00000001 0dc7faa0 0cf7afe0 00000003 0dc7fac8 00000004
假设这是一个32位进程,句柄是前四个单独的DWORD:“1f0”,“1f8”,“20c”和“1ec”。
您可以使用“!handle”WinDbg扩展程序查看每个句柄的详细信息,如下所示: !处理1f0 F. F标志将显示有关句柄的更多详细信息,包括其计数和名称(如果有一个与之关联)
如果您怀疑句柄是从托管代码传入的,那么您需要加载SOS或PSSCOR并使用!ClrStack命令显示托管调用堆栈详细信息。