要找出線程正在等待哪個對象,您必須進行一些調試。
首先,先從你有堆棧跟蹤:
0:000> CLRStack
OS線程ID:0x25a8(0)
ESP EIP
001af038 77455e74 [GCFrame:001af038]
001af108 77455e74 [HelperMethodFrame_1OBJ:001af108] System.Threading.Monitor.Enter(System.Object的)
001af160 00290192 ConsoleApplication1.MyClass.Main(System.String [])
001af3c0 70fc1b4c [GCFrame: 001af3c0]
找出正在調用Monitor.Enter()的幀。在這種情況下,它是MyClass的::主要(字串[] args)
001af160 00290192 ConsoleApplication1.MyClass.Main(System.String [])
現在,您需要拆卸調用者。使用!sos.u [eip]來做到這一點。
0:000> !u 00d10177
Normal JIT generated code
Program.Main(System.String[])
Begin 00d100f8, size 9d
00d100f8 55 push ebp
00d100f9 8bec mov ebp,esp
00d100fb 83ec10 sub esp,10h
00d100fe 894dfc mov dword ptr [ebp-4],ecx
00d10101 833de430970000 cmp dword ptr ds:[9730E4h],0
00d10108 7405 je 00d1010f
00d1010a e802a63b79 call mscorwks!JIT_DbgIsJustMyCode (7a0ca711)
00d1010f 33d2 xor edx,edx
00d10111 8955f8 mov dword ptr [ebp-8],edx
00d10114 90 nop
*** WARNING: Unable to verify checksum for C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\mscorlib\7bffd7ff2009f421fe5d229927588496\mscorlib.ni.dll
00d10115 b9fc7e3179 mov ecx,offset mscorlib_ni+0x257efc (79317efc) (MT: System.Threading.ThreadStart)
00d1011a e8ad1fc5ff call 009620cc (JitHelp: CORINFO_HELP_NEWSFAST_CHKRESTORE)
00d1011f 8945f4 mov dword ptr [ebp-0Ch],eax
00d10122 b858c09700 mov eax,97C058h
00d10127 50 push eax
00d10128 6864203b00 push 3B2064h
00d1012d 8b4df4 mov ecx,dword ptr [ebp-0Ch]
00d10130 33d2 xor edx,edx
00d10132 e8b9a45678 call mscorlib_ni+0x1ba5f0 (7927a5f0) (System.MulticastDelegate.CtorOpened(System.Object, IntPtr, IntPtr), mdToken: 060003bf)
00d10137 b9f8103379 mov ecx,offset mscorlib_ni+0x2710f8 (793310f8) (MT: System.Threading.Thread)
00d1013c e8c3c41679 call mscorwks!JIT_NewFast (79e7c604)
00d10141 8945f0 mov dword ptr [ebp-10h],eax
00d10144 8b55f4 mov edx,dword ptr [ebp-0Ch]
00d10147 8b4df0 mov ecx,dword ptr [ebp-10h]
00d1014a e8e1685c78 call mscorlib_ni+0x216a30 (792d6a30) (System.Threading.Thread..ctor(System.Threading.ThreadStart), mdToken: 060012ab)
00d1014f 8b45f0 mov eax,dword ptr [ebp-10h]
00d10152 8945f8 mov dword ptr [ebp-8],eax
00d10155 8b4df8 mov ecx,dword ptr [ebp-8]
00d10158 3909 cmp dword ptr [ecx],ecx
00d1015a e861695c78 call mscorlib_ni+0x216ac0 (792d6ac0) (System.Threading.Thread.Start(), mdToken: 060012b1)
00d1015f 90 nop
00d10160 8b0d30202e02 mov ecx,dword ptr ds:[22E2030h] ("Acquiring lock")
00d10166 e89d38a878 call mscorlib_ni+0x6d3a08 (79793a08) (System.Console.WriteLine(System.String), mdToken: 060007c8)
00d1016b 90 nop
00d1016c 8b0dfc1e2e02 mov ecx,dword ptr ds:[22E1EFCh] (Object: SyncBlock)
00d10172 e8ae281679 call mscorwks!JIT_MonEnterWorker (79e72a25)
>>> 00d10177 90 nop
00d10178 8b0d34202e02 mov ecx,dword ptr ds:[22E2034h] ("Releasing lock")
00d1017e e88538a878 call mscorlib_ni+0x6d3a08 (79793a08) (System.Console.WriteLine(System.String), mdToken: 060007c8)
00d10183 90 nop
00d10184 8b0dfc1e2e02 mov ecx,dword ptr ds:[22E1EFCh] (Object: SyncBlock)
00d1018a e8102b1679 call mscorwks!JIT_MonExitWorker (79e72c9f)
00d1018f 90 nop
00d10190 90 nop
00d10191 8be5 mov esp,ebp
00d10193 5d pop ebp
00d10194 c3 ret
請注意呼叫站點。此時,您有以下調試滲出:
00d1016c 8b0dfc1e2e02 mov ecx,dword ptr ds:[22E1EFCh] (Object: SyncBlock)
00d10172 e8ae281679 call mscorwks!JIT_MonEnterWorker (79e72a25)
>>> 00d10177 90 nop
00d10178 8b0d34202e02 mov ecx,dword ptr ds:[22E2034h] ("Releasing lock")
00d1017e e88538a878 call mscorlib_ni+0x6d3a08 (79793a08) (System.Console.WriteLine(System.String), mdToken: 060007c8)
00d10183 90 nop
就在調用JitMon :: Enter鍵(),你看到對象的地址將其移至ECX寄存器。這是你的線程正在等待的對象。
難道你不能從Visual Studio或其他IDE進行調試?如果你設置了一個斷點,你可以瀏覽所有正在等待它的線程,通過檢查它們的堆棧指針 – 2010-10-10 19:52:30
不,我正在試圖查看一個轉儲文件 – imak 2010-10-10 20:43:45
如果你正在尋找一種方法來獲得本地句柄線程等待的(實際的內核對象),那麼你可能會發現這篇文章很有用:http://blog.liranchen.com/2010/07/monitors-locking-primitive.html – Liran 2010-10-11 05:29:53