Determining which objects ZwWaitForMultipleObjects is waiting on
Asked Answered
C

1

7

Looking at a crash dump in windbg, I can see that all current threads are stalled at

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

or SingleObject variations of the same.

As a handle to the object to wait on is passed to ZwWaitForMultipleObjects, I assumed that I could work out which object it was using a variation of

!do <address>

with the right address -- but I don't know how to construct the right address. I'm assuming I need some offset from the ChildEBP?

Corelation answered 23/5, 2013 at 11:42 Comment(1)
!do is for managed objects (.NET) but ZwWFMO is most likely waiting on native handles. Use ~2kb to get a well documented Win32 frame further up the stack (hopefully WaitForMultipleObjects) and its first three args. You'll have to deref the second arg to get the handles. When you get the handle values use !handle <handle> f do get info about a particular handle. Post output to ~2kb if you need help on digging out the handle values.Koran
W
14

Try these steps:

  1. Use the "~2s" command to switch context to thread #2 (this step is arguably redundant but I find it easier to operate in the right thread context)

  2. Use the "kb" command to display the thread's call stack including each function's first three arguments. You will get something like:

    ChildEBP RetAddr  Args to Child 
    0dc7fa30 768b0962 00000004 0dc7fa80 00000001 ntdll!ZwWaitForMultipleObjects+0x15
    0dc7facc 73c61339 0dc7fa80 0dc7fb14 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x100
    
  3. Taking the above call stack as an example, you can see that the number of handles passed to ZwWaitForMultipleObjects is 4 (the value of the first argument). The address of the handle array is the second argument. In the above example the address is 0dc7fa80

  4. Use the "dd" command to display the contents of the handle array. In the case of the above call stack, use "dd 0dc7fa80" which will give something like:

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

    Assuming this is a 32bit process, the handles are the first four individual DWORDs: "1f0", "1f8", "20c" and "1ec".

  5. You can see the details of each handle using the "!handle" WinDbg extension like so: !handle 1f0 F The F flag will display more details about the handle, including its count and name (if it has one associated with it)

If you suspect the handles were passed in from managed code, then you'll need to load SOS or PSSCOR and use the !ClrStack command to display the managed call stack details.

Wommera answered 24/5, 2013 at 15:22 Comment(1)
Excellent, thanks Aeham (and Marc for the comment). That's perfect.Corelation

© 2022 - 2024 — McMap. All rights reserved.