2010-10-10 3 views
1

Если у меня есть следующая трассировка стека, где я вижу, что поток ожидает некоторую блокировку. Как я могу получить информацию об объекте, который ждет этот поток? Я думал, что должен иметь возможность команды SyncBlk, но похоже, что он может предоставлять информацию о блокировках и потоках своего владельца.Информация об объекте, что поток ожидает

0:000> !CLRStack 
OS Thread 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] 
+0

Не можете ли вы отлаживать из Visual Studio или другой среды IDE? Если вы установите точку останова, вы можете просмотреть все потоки, которые ждут ее, изучив их указатель стека –

+0

нет, я пытаюсь посмотреть файл дампа – imak

+0

Если вы ищете способ получить собственный дескриптор на который поток ожидает (фактический объект ядра), тогда вы можете найти это сообщение полезным: http://blog.liranchen.com/2010/07/monitors-locking-primitive.html – Liran

ответ

0

Чтобы узнать, к какому объекту ждет поток, вам нужно будет выполнить некоторую отладку.

Во-первых, начнем с трассировки стека, что у вас есть:

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 :: Main (string [] арг)

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. Это объект, который ждет ваш поток.

+0

Просто чтобы быть уверенным, что я правильно понял, вы говорите о 00d1016c 8b0dfc1e2e02 mov ecx, dword ptr ds: [22E1EFCh] (Object: SyncBlock), который означает, что поток объектов ожидает, является ли тот, который указан в 22E1EFCh правильно? – imak

+0

Также кажется, что подход использования! Dso, предложенный Брайаном, также дает мне правильный объект. Любые идеи о про или использовании этого подхода в сравнении с тем, что предложил Брайан? – imak

+0

Да, это правильно. Правильный объект находится в «! Do poi (22E1EFCh)». ! dso также может дать вам объект, которого вы ждете. Однако, если в потоке имеется несколько блокировок, вам, возможно, придется прибегнуть к разборке. В любом случае, хорошо иметь возможность читать некоторые демонстрации :) – feroze

0

Я дал ответ на ваш другой SO вопрос:

How to debug managed deadlocks.

+0

Использование SyncBlk Я могу получить информацию о замок и его владелец. То, что я хочу сделать здесь, - это то, что ждет этот поток.Так, например, в примере выше, смотря на стек tracem, этот поток ждет блокировки. Как я могу узнать, из какого объекта этот поток ждет отсюда. Если вы понимаете, о чем я? – imak

0

В параметрах ссылочных .NET методам выталкиваются в стек перед вызовом метода, так что вы должны найти аргумент для Monitor.Enter в верхней части стека, если вы делаете !dso для рассматриваемой темы. Это объект, который пытается заблокировать код.

Если вы сопоставляете адрес этого с выводом !threads, вы можете узнать, какой поток в данный момент имеет этот замок (если есть).

 Смежные вопросы

  • Нет связанных вопросов^_^