Информация о объекте, которую ждет нить

StackOverflow https://stackoverflow.com/questions/3901855

  •  29-09-2019
  •  | 
  •  

Вопрос

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

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: 000>! Clrstack
Идентификатор потока ОС: 0x25A8 (0)
ESP EIP
001AF038 77455E74 [GCRAME: 001AF038
001AF108 77455E74 [helpermethodframe_1obj: 001af108] System.Threading.Monitor.Enter (System.Object)
001AF160 00290192 Конкресовое объяснение1.myclass.main (System.String [])
001AF3C0 70FC1B4C [GCRAME: 001AF3C0

Узнайте кадр, которая вызывает ROINE.ENTER (). В этом случае это MyClass :: Main (String [] args)

001AF160 00290192 Конкресовое объяснение1.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. Это тот объект, который ждет ваш поток.

Другие советы

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

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

Я дал ответ в другом вашем вопросе:

Как отлаживать управляемые тупики.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top