我在申请方面遇到了僵局。 我对转储的研究给出了以下结果: 1)有几个主题:
0:022> !threads ThreadCount: 23 UnstartedThread: 1 BackgroundThread: 21 PendingThread: 1 DeadThread: 0 Hosted Runtime: no Lock ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception 0 1 bc8 01108a10 26020 Preemptive 00000000:00000000 01102c30 0 STA 2 2 1380 011169c0 2b220 Preemptive 00000000:00000000 01102c30 0 MTA (Finalizer) 4 3 a1c 011c9c28 102a220 Preemptive 00000000:00000000 01102c30 0 MTA (Threadpool Worker) 5 4 13dc 011a1118 1020220 Preemptive 00000000:00000000 01102c30 0 Ukn (Threadpool Worker) 7 7 11dc 0793ff00 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 8 8 e08 0798a910 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 9 9 1314 07a11800 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 10 10 c40 07a2ee40 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 11 11 dfc 07a1cf68 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 12 12 ed8 07a8bcb0 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 19 13 1328 07a8c1f8 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 14 14 1114 07a9c970 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 15 15 10ac 07a8d0f8 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 16 16 ad8 07a8d918 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 17 17 640 07a72d98 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 18 18 620 07a72308 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 13 19 1198 07a70de8 20220 Preemptive 00000000:00000000 01102c30 0 Ukn 20 20 594 07a6f380 1029220 Preemptive 00000000:00000000 01102c30 0 MTA (Threadpool Worker) 21 21 116c 07a6f8c8 1039220 Preemptive 00000000:00000000 01102c30 0 Ukn (Threadpool Worker) 22 24 fb4 0c7c2340 1029220 Cooperative 00000000:00000000 01102c30 2 MTA (GC) (Threadpool Worker) 23 5 b10 0a9c6608 8039220 Preemptive 00000000:00000000 01102c30 0 Ukn (Threadpool Completion Port) 24 6 164 0c7c6298 8029220 Preemptive 00000000:00000000 01102c30 0 MTA (Threadpool Completion Port) 26 23 e9c 07a71330 1600 Preemptive 00000000:00000000 01102c30 0 Ukn
2)线程0,9,12,13,14,15,16,17,18,19,20,21和23等待GC完成。因为他们有类似的callstack。像这样:
00 048fec90 76c12cc7 000001bc 00000000 00000000 ntdll!NtWaitForSingleObject+0xc (FPO: [3,0,0]) 01 048fed04 74d74b85 000001bc ffffffff 00000000 KERNELBASE!WaitForSingleObjectEx+0x99 (FPO: [SEH]) 02 048fed34 74d74bcc 00000000 3629c685 00000000 clr!CLREventWaitHelper2+0x31 (FPO: [Non-Fpo]) 03 048fed84 74d74b4f 00000000 3629c6bd 0a9c6608 clr!CLREventWaitHelper+0x2a (FPO: [Non-Fpo]) 04 048fedbc 74e52c82 ffffffff 00000000 00000000 clr!CLREventBase::WaitEx+0x152 (FPO: [Non-Fpo]) 05 048fedd0 74e55e8d 00000000 3629c6e1 0a9c6608 clr!WKS::GCHeap::WaitUntilGCComplete+0x34 (FPO: [1,0,0]) 06 048fee20 74d698cc 00000005 048fee64 ffffffff clr!Thread::RareDisablePreemptiveGC+0x1dc (FPO: [0,13,0]) ...
3)线程22的调用堆栈看起来像是在等待某事:
00 0a26e730 76c12cc7 000001c8 00000000 00000000 ntdll!NtWaitForSingleObject+0xc (FPO: [3,0,0]) 01 0a26e7a4 74d74b85 000001c8 ffffffff 00000000 KERNELBASE!WaitForSingleObjectEx+0x99 (FPO: [SEH]) 02 0a26e7d4 74d74bcc 00000000 3880c325 00000000 clr!CLREventWaitHelper2+0x31 (FPO: [Non-Fpo]) 03 0a26e824 74d74b4f 00000000 3880c35d 07a71330 clr!CLREventWaitHelper+0x2a (FPO: [Non-Fpo]) 04 0a26e85c 74ef33a9 ffffffff 00000000 00000000 clr!CLREventBase::WaitEx+0x152 (FPO: [Non-Fpo]) 05 0a26e878 74ef33da 3880c3b9 753b11d0 00000000 clr!WKS::gc_heap::create_bgc_thread+0x4e (FPO: [0,0,0]) 06 0a26e8b8 74e4f783 00000010 00000000 00000003 clr!WKS::gc_heap::garbage_collect+0x38a (FPO: [Non-Fpo]) 07 0a26e8e0 74e52be0 00000000 00000000 0c7c2380 clr!WKS::GCHeap::GarbageCollectGeneration+0x203 (FPO: [2,5,4]) 08 0a26e904 74e4f0db 00000000 0b48bb5c 0c7c2380 clr!WKS::gc_heap::try_allocate_more_space+0x157 (FPO: [Non-Fpo]) 09 0a26e91c 74e4f24f 00000000 00000010 010fd130 clr!WKS::gc_heap::allocate_more_space+0x18 (FPO: [1,0,0]) 0a 0a26e934 74d692e6 00000010 00000010 00000002 clr!WKS::GCHeap::Alloc+0x4f (FPO: [Non-Fpo]) ...
此线程的Dumpstack看起来像这样:
ChildEBP RetAddr Caller, Callee
0a26e730 76c12cc7 KERNELBASE!WaitForSingleObjectEx+0x99, calling ntdll!NtWaitForSingleObject
0a26e7a4 74d74b85 clr!CLREventWaitHelper2+0x31
0a26e7d4 74d74bcc clr!CLREventWaitHelper+0x2a, calling clr!CLREventWaitHelper2
0a26e824 74d74b4f clr!CLREventBase::WaitEx+0x152, calling clr!CLREventWaitHelper
0a26e83c 74df70ea clr!Thread::StartThread+0x71, calling clr!_EH_epilog3
0a26e85c 74ef33a9 clr!WKS::gc_heap::create_bgc_thread+0x4e, calling clr!CLREventBase::WaitEx
0a26e878 74ef33da clr!WKS::gc_heap::garbage_collect+0x38a, calling clr!WKS::gc_heap::create_bgc_thread
0a26e894 74e52b98 clr!WKS::gc_heap::wait_for_bgc_high_memory+0x111, calling clr!__security_check_cookie
0a26e8b8 74e4f783 clr!WKS::GCHeap::GarbageCollectGeneration+0x203, calling clr!WKS::gc_heap::garbage_collect
0a26e8e0 74e52be0 clr!WKS::gc_heap::try_allocate_more_space+0x157, calling clr!WKS::GCHeap::GarbageCollectGeneration
0a26e904 74e4f0db clr!WKS::gc_heap::allocate_more_space+0x18, calling clr!WKS::gc_heap::try_allocate_more_space
0a26e91c 74e4f24f clr!WKS::GCHeap::Alloc+0x4f, calling clr!WKS::gc_heap::allocate_more_space
0a26e934 74d692e6 clr!Alloc+0x54
0a26e954 74d6940f clr!AllocateObject+0x94, calling clr!Alloc
0a26e970 74d73bf6 clr!ObjIsInstanceOfNoGC+0x13d, calling clr!MethodTable::CanCastToClassNoGC
0a26e98c 74d62adc clr!HelperMethodFrame::Push+0x10, calling clr!GetThread
0a26e994 74d694a3 clr!JIT_New+0x6b, calling clr!AllocateObject
0a26e9cc 0825f15f (MethodDesc 08201884 +0x97 NHibernate.Loader.Loader.InstanceNotYetLoaded(System.Data.IDataReader, Int32, NHibernate.Persister.Entity.ILoadable, NHibernate.Engine.EntityKey, NHibernate.LockMode, System.String, NHibernate.Engine.EntityKey, System.Object, System.Collections.IList, NHibernate.Engine.ISessionImplementor)), calling 0757329e
0a26e9e4 0825ec49 (MethodDesc 0820186c +0x129 NHibernate.Loader.Loader.GetRow(System.Data.IDataReader, NHibernate.Persister.Entity.ILoadable[], NHibernate.Engine.EntityKey[], System.Object, NHibernate.Engine.EntityKey, NHibernate.LockMode[], System.Collections.IList, NHibernate.Engine.ISessionImplementor)), calling (MethodDesc 08201884 +0 NHibernate.Loader.Loader.InstanceNotYetLoaded(System.Data.IDataReader, Int32, NHibernate.Persister.Entity.ILoadable, NHibernate.Engine.EntityKey, NHibernate.LockMode, System.String, NHibernate.Engine.EntityKey, System.Object, System.Collections.IList, NHibernate.Engine.ISessionImplementor))
...
所以,我已经查看了coreclr的源代码并发现,在第一步gc_heap::create_bgc_thread
启动了一个工作线程并等待(INFINITE)直到这个sthead将被启动:
#else // FEATURE_REDHAWK
Thread* current_bgc_thread;
gh->bgc_thread = SetupUnstartedThread(FALSE);
if (!(gh->bgc_thread))
{
goto cleanup;
}
current_bgc_thread = gh->bgc_thread;
if (!current_bgc_thread->CreateNewThread (0, &(gh->bgc_thread_stub), gh))
{
goto cleanup;
}
current_bgc_thread->SetBackground (TRUE, FALSE);
// wait for the thread to be in its main loop, this is to detect the situation
// where someone triggers a GC during dll loading where the loader lock is
// held.
current_bgc_thread->StartThread();
#endif // FEATURE_REDHAWK
{
dprintf (2, ("waiting for the thread to reach its main loop"));
// In chk builds this can easily time out since
// now we need to set the thread up into a managed thead.
// And since it's a managed thread we also need to make sure that we don't
// clean up here and are still executing code on that thread (it'll
// trigger all sorts of asserts.
//DWORD res = gh->background_gc_create_event.Wait(20,FALSE);
DWORD res = gh->background_gc_create_event.Wait(INFINITE,FALSE);
if (res == WAIT_TIMEOUT)
因此,看起来create_bgc_thread等待一个线程无法恢复(Thread::StartThread
只调用::ResumeThread
)。
在倾销堆中有一条奇怪的线,我真的不明白:
0a26e83c 74df70ea clr!Thread::StartThread+0x71, calling clr!_EH_epilog3
这意味着什么?它是clr的异常/崩溃吗?
答案 0 :(得分:1)
这是一个可能有助于您理解的Microsoft doc on prologs and epilogs。
基于此blog on Microsoft exception handling看起来_EH_epilog3
是内置的epilog函数。
我的猜测是,该线程可能抛出了一个未处理的异常?