关键部分如何由死线程拥有?

时间:2015-06-02 23:39:31

标签: .net winforms windbg critical-section sos

我有一个.NET Winform应用程序及其UI挂起。

CritSec ntdll!LdrpLoaderLock+0 at 774920c0上阻止了UI线程。

0:010> kb
ChildEBP RetAddr  Args to Child              
0fc4e034 773c8df4 000000d4 00000000 00000000 ntdll!NtWaitForSingleObject+0x15
0fc4e098 773c8cd8 00000000 00000000 773bfa84 ntdll!RtlpWaitOnCriticalSection+0x13e
0fc4e0c0 773bffd3 774920c0 71e65850 00000001 ntdll!RtlEnterCriticalSection+0x150
0fc4e230 773bfd2f 00000001 00000001 00000000 ntdll!LdrGetDllHandleEx+0x2f7
0fc4e24c 75dd1a43 00000001 00000000 0fc4e2bc ntdll!LdrGetDllHandle+0x18
WARNING: Stack unwind information not available. Following frames may be wrong.
0fc4e2a0 75dd1c57 0fc4e2bc b7a43509 02baed94 KERNELBASE!GetModuleFileNameW+0x1a9
0fc4e718 75dd1d52 00000001 00000002 02baed94 KERNELBASE!GetModuleFileNameW+0x3bd
0fc4e730 5fc58fc5 02baed94 b108f787 7285ac08 KERNELBASE!GetModuleHandleW+0x29
...

关键部分774920c0归线程1bd4所有。

0:010> !locks
CritSec ntdll!LdrpLoaderLock+0 at 774920c0
WaiterWoken        No
LockCount          32
RecursionCount     1
OwningThread       1bd4
EntryCount         0
ContentionCount    27a
*** Locked

CritSec +1027c5bc at 1027c5bc
WaiterWoken        No
LockCount          3
RecursionCount     1
OwningThread       1a4c
EntryCount         0
ContentionCount    1bb
*** Locked

CritSec +17700138 at 17700138
WaiterWoken        No
LockCount          1
RecursionCount     1
OwningThread       1620
EntryCount         0
ContentionCount    d
*** Locked

线程1bd4的Windbg线程序列ID为68

0:010> ~
#  0  Id: ccc.124c Suspend: 1 Teb: 7efdd000 Unfrozen
   1  Id: ccc.88c Suspend: 1 Teb: 7efda000 Unfrozen
   ...
   67  Id: ccc.514 Suspend: 1 Teb: 7ef36000 Unfrozen
   68  Id: ccc.1bd4 Suspend: 1 Teb: 7ef30000 Unfrozen
   69  Id: ccc.1a30 Suspend: 1 Teb: 7ef1b000 Unfrozen
   ...

但是,68的输出中不存在!threads,或者这是否意味着68是一个死线程?

0:010> !threads
ThreadCount:      65
UnstartedThread:  13
BackgroundThread: 37
PendingThread:    13
DeadThread:       5
Hosted Runtime:   no
                                                                         Lock  
       ID OSID ThreadOBJ    State GC Mode     GC Alloc Context  Domain   Count Apt Exception
   0    1 124c 004db888     26020 Preemptive  3E3A01CC:00000000 004cf1b0 0     STA 
   2    2 14e0 004e7a20     2b220 Preemptive  00000000:00000000 004cf1b0 0     MTA (Finalizer) 
 ...
   8   10 19c4 055691e0   3029220 Preemptive  00000000:00000000 004cf1b0 0     MTA (Threadpool Worker) 
  10   12 1520 0f91cbc8     27220 Preemptive  00000000:00000000 004cf1b0 0     STA
 ...
  66   46 169c 29e344b8   3029220 Preemptive  00000000:00000000 004cf1b0 0     MTA (Threadpool Worker) 
XXXX   33    0 19ff4a90   8039820 Preemptive  00000000:00000000 004cf1b0 0     Ukn (Threadpool Completion Port) 
XXXX   55    0 29cbe540   8039820 Preemptive  00000000:00000000 004cf1b0 0     Ukn (Threadpool Completion Port) 
  69    6 1a30 2a1be4d8   a029220 Preemptive  00000000:00000000 004cf1b0 0     MTA (Threadpool Completion Port) 
 ...

当我尝试使用68遍历!clrstack的调用堆栈时,它会失败。但我仍然可以使用kb来检查其本机堆栈跟踪。

0:068> !clrstack
OS Thread Id: 0x1bd4 (68)
Unable to walk the managed stack. The current thread is likely not a 
managed thread. You can run !threads to get a list of managed threads in
the process
Failed to start stack walk: 80070057
0:068> kb
ChildEBP RetAddr  Args to Child              
2c85f580 773c8df4 000019ac 00000000 00000000 ntdll!NtWaitForSingleObject+0x15
2c85f5e4 773c8cd8 00000000 00000000 2bc40458 ntdll!RtlpWaitOnCriticalSection+0x13e
2c85f60c 773f5f33 17700138 52a74c34 175f3f40 ntdll!RtlEnterCriticalSection+0x150
2c85f654 773c740d 00000000 17700000 2bc404b8 ntdll!RtlpFreeUserBlock+0x47
2c85f690 773be023 2bc404b8 3b6af630 27620000 ntdll!RtlpLowFragHeapFree+0x2cc
2c85f6a8 75a814ad 17700000 00000000 2bc404b8 ntdll!RtlFreeHeap+0x105
WARNING: Stack unwind information not available. Following frames may be wrong.

我可以看到线程68在另一个关键部分17700138上被阻止,该部分属于另一个线程1620。这应该是UI线程挂起的根本原因。

但我的问题是线程68的真相是什么?如果它已经死了,它怎么能拥有关键部分CritSec ntdll!LdrpLoaderLock+0 at 774920c0并且有它的调用堆栈?

0 个答案:

没有答案