관리되는 (C#) 코드와 관리되지 않는 (C++) 코드가 혼합되어있는 응용 프로그램에 문제가 있습니다. 기본적으로 우리는 한 무리의 어셈블리를 호출하는 exe를 가지고 있으며이 어셈블리 중 하나는 C + + 라이브러리의 MC++ 래퍼입니다. 응용 프로그램은 콘솔 응용 프로그램입니다. 대부분의 경우 잘 작동하지만 가끔 오류나 예외없이 중단됩니다.GC 스레드 교착 상태로 .NET 응용 프로그램이 응답하지 않음
메모리 덤프와 심볼을 사용하여 WinDbg에서 진단을 할 수 있었지만 실제로 어떤 것이 교착 상태인지 알 수 없습니다. 스택에 올라와 있지만 하나의 스레드가 메모리 할당을 시도하고 GC로 교착 상태가되는 경우를 찾을 수 없었던 CLR 메서드 이름을 검색했습니다.
지금까지 sos, sosex, psscor4 확장을 사용하여 WinDbg를 시도했습니다. intrestingly sosex는 교착 상태 (! dlk)를 확인하는 명령을 가지고 있지만 교착 상태는보고하지 않습니다.
크고 복잡한 앱이므로 코드를 게시하기가 어렵습니다. .NET 3.5와 4.0 어셈블리가 혼합되어 있습니다. 관리되는 코드와 관리되지 않는 코드 모두에 스레드가 있습니다.
누군가가 스택 추적을보고 이것이 GC 스레드로 인해 교착 상태가 될 수 있다고 확신하는 경우 나는 사과 할 것입니다. 또는 C# 및 MC++를 사용하는 .NET 응용 프로그램에서 교착 상태/중단을 디버깅하는 다른 방법을 제안 할 수 있다면 더 좋습니다. 스레드의
목록을 응용 프로그램이 정지 할 때 : 여기
는 지금까지이 무엇ThreadCount: 8
UnstartedThread: 0
BackgroundThread: 5
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
PreEmptive Lock
ID OSID ThreadOBJ State GC GC Alloc Context Domain Count APT Exception
0 1 de0 00000000008069f0 a020 Enabled 0000000000000000:0000000000000000 00000000007fa280 0 MTA
2 2 2130 000000000080bd30 b220 Enabled 0000000000000000:0000000000000000 00000000007fa280 0 MTA (Finalizer)
4 3 14fc 000000001d182880 200b020 Enabled 0000000000000000:0000000000000000 00000000007fa280 0 MTA
5 4 20d0 000000001d18b400 b220 Enabled 0000000000000000:0000000000000000 00000000007fa280 2 MTA (GC)
6 5 18a8 000000001d19f6a0 b020 Enabled 0000000000000000:0000000000000000 00000000007fa280 0 MTA
7 6 18a0 000000001d1c6f10 220 Enabled 0000000000000000:0000000000000000 00000000007fa280 0 Ukn
8 7 12f4 000000001d1c1ee0 220 Enabled 0000000000000000:0000000000000000 00000000007fa280 0 Ukn
10 8 2170 000000001d1c2ad0 220 Enabled 0000000000000000:0000000000000000 00000000007fa280 0 Ukn
OSID Special thread type
1 2570 DbgHelper
2 2130 Finalizer
5 20d0 SuspendEE
12 1890 GC
이것은 GC 스레드의 스택 모습입니다 (스레드!) :
OS Thread Id: 0x1890 (12)
Child-SP RetAddr Call Site
0000000023e9f898 000000007799e4e8 ntdll!ZwWaitForSingleObject+0xa
0000000023e9f8a0 000000007799e3db ntdll!RtlpWaitOnCriticalSection+0xe8
0000000023e9f950 000007fef95d603e ntdll!RtlEnterCriticalSection+0xd1
0000000023e9f980 000007fef947bc41 clr!UnsafeEEEnterCriticalSection+0x1f
0000000023e9f9b0 000007fef947613a clr!CrstBase::Enter+0x1a1
0000000023e9f9f0 000007fef95da3a2 clr!ThreadStore::LockThreadStore+0x9a
0000000023e9fa20 000007fef9679675 clr!WKS::GCHeap::SuspendEE+0x82
0000000023e9fb20 000007fef9677eb2 clr!WKS::gc_heap::bgc_suspend_EE+0x25
0000000023e9fb50 000007fef98455b0 clr!WKS::gc_heap::background_mark_phase+0x236
0000000023e9fbb0 000007fef9677b76 clr! ?? ::FNODOBFM::`string'+0x9f85d
0000000023e9fc00 00000000773d652d clr!WKS::gc_heap::gc_thread_function+0xd3
0000000023e9fc30 000000007797c521 KERNEL32!BaseThreadInitThunk+0xd
0000000023e9fc60 0000000000000000 ntdll!RtlUserThreadStart+0x1d
내게는 GC 스레드가 중요 섹션을 기다리고있는 것 같습니다. 크리티컬 섹션 주소를 찾아 소유자 스레드 (! critsec)를 찾을 수있었습니다. 소유자 스레드의 스택은 다음과 같습니다. 나는이 게시물을 짧게 유지하기 위해 그것을 다듬었다. 두 번째 호출 스택에서이 줄은 의심스러운
OS Thread Id: 0x20d0 (5)
Child-SP RetAddr Call Site
000000001fc5dd38 000007fefe0510dc ntdll!ZwWaitForSingleObject+0xa
000000001fc5dd40 000007fef9478817 KERNELBASE!WaitForSingleObjectEx+0x79
000000001fc5dde0 000007fef94787c0 clr!CLREvent::WaitEx+0x170
000000001fc5de20 000007fef947866b clr!CLREvent::WaitEx+0xf8
000000001fc5de80 000007fef967a15b clr!CLREvent::WaitEx+0x5e
000000001fc5df20 000007fef967a001 clr!WKS::gc_heap::user_thread_wait+0x49
000000001fc5df50 000007fef95dbb4e clr! ?? ::FNODOBFM::`string'+0x9fcc4
000000001fc5e030 000007fef95da22e clr!WKS::GCHeap::GarbageCollectGeneration+0x14e
000000001fc5e080 000007fef95d9e4e clr!WKS::gc_heap::try_allocate_more_space+0x25f
000000001fc5e150 000007fef95d9fc8 clr!WKS::GCHeap::Alloc+0x7e
000000001fc5e180 000007fef947407c clr!AllocateArrayEx+0xa6b
000000001fc5e2f0 000007fef8555b75 clr!JIT_NewArr1+0x45c
000000001fc5e4c0 000007fef8561103 mscorlib_ni!System.Reflection.CustomAttributeData.GetCustomAttributeRecords(System.Reflection.RuntimeModule, Int32)+0x115
000000001fc5e590 000007fef855db55 mscorlib_ni!System.Reflection.CustomAttribute.IsCustomAttributeDefined(System.Reflection.RuntimeModule, Int32, System.RuntimeType, Boolean)+0x103
000000001fc5e720 000007fef856c8ac mscorlib_ni!System.Reflection.CustomAttribute.IsDefined(System.RuntimeType, System.RuntimeType, Boolean)+0x75
000000001fc5e770 000007fef857fe46 mscorlib_ni!System.Enum.InternalFormat(System.RuntimeType, System.Object)+0x2c
000000001fc5e7b0 000007fef8554f3b mscorlib_ni!System.Text.StringBuilder.AppendFormat(System.IFormatProvider, System.String, System.Object[])+0x2e6
000000001fc5e850 000007ff03c640fc mscorlib_ni!System.String.Format(System.IFormatProvider, System.String, System.Object[])+0x7b
000000001fc5e8b0 000007ff03c638a6 MyLibrary1!NumberCache.NumberEntry.ToString()+0x26c
디버그 진단을 사용하여 덤프를 분석 할 수 있습니다. 이는 Sosex보다 몇 가지 교착 상태 패턴을 분석 할 수 있기 때문입니다. 그러나 교착 상태가 인간에 의해서조차 이해하기에는 너무 복잡하기 때문에 자동 도구로 모든 패턴을 식별 할 수는 없습니다. 여유가 있다면 http://support.microsoft.com을 통해 지원 사례를 열어 Microsoft에 문의하십시오. –
@LexLi, Debug Diag 제안에 감사드립니다. 이전에 나왔지만 너무 특이한 것으로 보였으므로이를 기각했습니다. 이전 mem 덤프 중 하나를 통해 실행했고 기본적으로 동일한 스레드를 가리키는 것입니다. GC 스레드는 다른 스레드가 소유 한 crit 초를 기다리고 있습니다. 어느 쪽이 교착 상태에 대한 어떤 확신을 주는지. Debug Diag는 동일한 psscor4 확장을 사용합니다. 또한 우리는 MS 지원 옵션도 찾고 있습니다. 감사! – user1210698
나는 모든 파이널 라이저 구현 (~)을 점검해야한다고 생각한다. finalizers에 교착 상태가있는 것 같습니다 – 6opuc