我有一个.NET进程的完整内存转储。我想研究一个主题。具体来说,我想知道等待多长时间。
这是!ClrStack:
0:049> !CLRStack
OS Thread Id: 0x1170 (49)
Child SP IP Call Site
000000002139e308 0000000076f7e18a [HelperMethodFrame_1OBJ: 000000002139e308] System.Threading.WaitHandle.WaitOneNative(System.Runtime.InteropServices.SafeHandle, UInt32, Boolean, Boolean)
000000002139e430 000007fef7d43264 System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle, Int64, Boolean, Boolean)
000000002139e470 000007fef85e4407 System.Threading.WaitHandle.WaitOne(System.TimeSpan, Boolean)
000000002139e4b0 000007fe9b66b0a4 BJE.CriticalThreadManager.Pause(BJE.ICriticalThread, BJE.CriticalThreadImportance, System.Threading.WaitHandle) [d:\tfs\RTQA150520\SharpTop\BJE\BJE\ICriticalThread.cs @ 297]
000000002139e540 000007fe9b66a600 BJE.CriticalThreadManager.CriticalThreadMain(BJE.ICriticalThread, BJE.CriticalThreadOptionsAttribute, System.Threading.AutoResetEvent) [d:\tfs\RTQA150520\SharpTop\BJE\BJE\ICriticalThread.cs @ 238]
000000002139e610 000007fef7d239a5 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
000000002139e770 000007fef7d23719 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
000000002139e7a0 000007fef7d236f7 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
000000002139e7f0 000007fef7d3adc1 System.Threading.ThreadHelper.ThreadStart()
000000002139eb08 000007fef8f1a7f3 [GCFrame: 000000002139eb08]
000000002139ee58 000007fef8f1a7f3 [DebuggerU2MCatchHandlerFrame: 000000002139ee58]
所以,我知道线程正在等待。问题是!CLRStack -a
没有告诉我等待的参数:
0:049> !CLRStack -a
OS Thread Id: 0x1170 (49)
Child SP IP Call Site
000000002139e308 0000000076f7e18a [HelperMethodFrame_1OBJ: 000000002139e308] System.Threading.WaitHandle.WaitOneNative(System.Runtime.InteropServices.SafeHandle, UInt32, Boolean, Boolean)
000000002139e430 000007fef7d43264 System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle, Int64, Boolean, Boolean)
PARAMETERS:
waitableSafeHandle = <no data>
millisecondsTimeout = <no data>
hasThreadAffinity = <no data>
exitContext = <no data>
LOCALS:
<no data>
000000002139e470 000007fef85e4407 System.Threading.WaitHandle.WaitOne(System.TimeSpan, Boolean)
PARAMETERS:
this = <no data>
timeout = <no data>
exitContext = <no data>
LOCALS:
<CLR reg> = 0x0000000000000000
...
我可以查看本机堆栈跟踪:
0:049> kb
RetAddr : Args to Child : Call Site
000007fe`fcd21430 : ffffffff`fffffffe 000007fe`f8f15a1f 48d34863`a6a8cbd7 00000000`80114f80 : ntdll!NtWaitForMultipleObjects+0xa
00000000`76d31753 : 00000000`2139dfc8 00000000`2139dfc0 00000000`00000000 00000003`8d0d45d0 : KERNELBASE!WaitForMultipleObjectsEx+0xe8
000007fe`f9038976 : 00000000`0001d4c0 00000000`2139e270 00000000`2139e308 00000000`2139e129 : kernel32!WaitForMultipleObjectsExImplementation+0xb3
000007fe`f903877a : 00000000`00000001 00000000`0001d4c0 00000003`5ed4e343 00000000`00000001 : clr!WaitForMultipleObjectsEx_SO_TOLERANT+0x62
000007fe`f9038591 : 00000000`00000000 00000000`00000001 00000000`00000000 00000000`00000001 : clr!Thread::DoAppropriateWaitWorker+0x1d0
000007fe`f9048411 : 00000000`00000000 00000000`00000001 00000000`00000000 00000000`00000000 : clr!Thread::DoAppropriateWait+0x7d
000007fe`f7d43264 : 01d17a4c`8431cbd7 00000000`0001d4c0 00000000`80122700 000007fe`9b66b700 : clr!WaitHandleNative::CorWaitOneNative+0x175
000007fe`f85e4407 : 00000000`80114f80 000007fe`9b66b729 00000000`801224e8 00000004`0015e7e8 : mscorlib_ni+0x4c3264
000007fe`9b66b0a4 : 00000000`80114f80 00000000`47868c00 00000000`801224e8 00000000`80114f80 : mscorlib_ni+0xd64407
000007fe`9b66a600 : 00000000`805ba018 00000000`803e8558 00000000`00000001 00000000`805c3b88 : 0x000007fe`9b66b0a4
000007fe`f7d239a5 : 00000000`801224e8 00000000`80114f80 00000000`80122758 00000000`80122708 : 0x000007fe`9b66a600
000007fe`f7d23719 : 00000000`000a0008 00000000`770426d0 0044005c`003a0064 006f0066`00790061 : mscorlib_ni+0x4a39a5
000007fe`f7d236f7 : 00000003`8023bdf0 00380043`00460054 00540045`004e0030 006c006c`0064002e : mscorlib_ni+0x4a3719
000007fe`f7d3adc1 : 00000000`805c4058 00000000`00000000 00000000`00000000 00000000`00000000 : mscorlib_ni+0x4a36f7
000007fe`f8f1a7f3 : 00000000`805c4080 00000000`00000001 00000000`00000000 00000000`00000000 : mscorlib_ni+0x4badc1
000007fe`f8f1a6de : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : clr!CallDescrWorkerInternal+0x83
000007fe`f8f1ae76 : 00000000`00000001 00000000`00000004 00000000`2139eb08 00000000`2139ebc8 : clr!CallDescrWorkerWithHandler+0x4a
000007fe`f90c969d : 00000000`2139ef80 00000000`2139eec0 000007fe`f7f6bf38 00000000`176cb400 : clr!MethodDescCallSite::CallTargetWorker+0x251
000007fe`f8f1c121 : 00000000`805c4080 00000000`2139eec0 00000000`176cb400 000007fe`f8e35f08 : clr!ThreadNative::KickOffThread_Worker+0x105
000007fe`f8f1c0a8 : 00000000`2139eec0 000007fe`f8f12ba4 00000000`2139edd0 000007fe`f8f13a6a : clr!ManagedThreadBase_DispatchInner+0x2d
000007fe`f8f1c019 : 00000000`00000001 006f0066`00000001 005c0065`00630072 005c0045`004a0042 : clr!ManagedThreadBase_DispatchMiddle+0x6c
000007fe`f8f1c15f : ffffffff`ffffffff 00000000`176cb400 00000000`00000000 00000000`00000000 : clr!ManagedThreadBase_DispatchOuter+0x75
000007fe`f90c957e : 00000000`176cb400 00000000`00000001 00000000`00000000 00000000`00000008 : clr!ManagedThreadBase_FullTransitionWithAD+0x2f
000007fe`f905fcb6 : 00000000`0caef010 00000000`176cb400 00000000`2139ef58 00000000`00000000 : clr!ThreadNative::KickOffThread+0xd2
00000000`76d259cd : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : clr!Thread::intermediateThreadProc+0x7d
00000000`76f5b891 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0xd
00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d
KERNELBASE!WaitForMultipleObjectsEx似乎是一个众所周知的函数,具有以下签名:
DWORD WINAPI WaitForMultipleObjectsEx(
_In_ DWORD nCount,
_In_ const HANDLE *lpHandles,
_In_ BOOL bWaitAll,
_In_ DWORD dwMilliseconds,
_In_ BOOL bAlertable
);
但是,我很难将该函数的kb
输出映射到其预期参数。
确实,kb
声称将以下参数传递给该函数:
00000000`2139dfc8 00000000`2139dfc0 00000000`00000000 00000003`8d0d45d0
鉴于方法签名,它们对我没有多大意义,但对我来说很明显我误解了一些东西。
如何在这里找出参数值?
修改
0:049> kn 3
# Child-SP RetAddr Call Site
01 00000000`2139de90 00000000`76d31753 KERNELBASE!WaitForMultipleObjectsEx+0xe8
02 00000000`2139df90 000007fe`f9038976 kernel32!WaitForMultipleObjectsExImplementation+0xb3
03 00000000`2139e020 000007fe`f903877a clr!WaitForMultipleObjectsEx_SO_TOLERANT+0x62
0:049> .frame /c /r 1
01 00000000`2139de90 00000000`76d31753 KERNELBASE!WaitForMultipleObjectsEx+0xe8
rax=00000008b7f8fd38 rbx=000000002139dfc0 rcx=0000000000601eb0
rdx=0000000000000000 rsi=0000000000000001 rdi=0000000000000001
rip=000007fefcd21430 rsp=000000002139de90 rbp=0000000000000001
r8=00000004c4990798 r9=00000000176cb400 r10=000007fe997ce068
r11=0000000300f58448 r12=000000002139ded8 r13=000000002139df30
r14=0000000000000001 r15=0000000000000001
iopl=0 nv up ei pl zr na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
KERNELBASE!WaitForMultipleObjectsEx+0xe8:
000007fe`fcd21430 8bd8 mov ebx,eax