Abbiamo un problema con la nostra applicazione che utilizza una combinazione di codice gestito (C#) e non gestito (C++). Fondamentalmente abbiamo un exe che richiama un gruppo di assembly e uno di questi assembly è un wrapper MC++ della nostra libreria C++. L'applicazione è un'app per console. La maggior parte delle volte funziona bene, ma occasionalmente si blocca senza errori o eccezioni.Applicazione .NET si blocca con deadlock thread GC
Usando i dump e i simboli di memoria siamo riusciti a fare qualche diagnosi in WinDbg ma non sono sicuro che quello che stiamo vedendo sia un deadlock o meno. Ho cercato i nomi dei metodi CLR presenti nello stack ma non sono stato in grado di trovare casi in cui un thread sta tentando di allocare memoria e si blocca con GC.
Finora ho provato WinDbg con le estensioni sos, sosex, psscor4. Interessante sosex ha un comando per verificare i deadlock (! Dlk) ma non segnala deadlock.
È difficile pubblicare il codice perché è un'app ampia e complessa. Esiste una combinazione di assembly .NET 3.5 e 4.0. Esistono thread sia nel codice gestito che non gestito.
Sarei grato se qualcuno potesse esaminare le tracce dello stack e confermare che si tratta di un possibile deadlock con thread GC. O ancora meglio se puoi suggerire un altro modo per eseguire il debug di deadlock/hang in app .NET che usano C# e MC++.
Ecco quello che ho finora:
Elenco dei thread quando l'applicazione si blocca:
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
Questo è ciò che lo stack del thread GC assomiglia (discussioni!):
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
Per me sembra che il thread GC sia in attesa della sezione critica. Siamo stati in grado di trovare l'indirizzo della sezione critica e quindi trovare il thread proprietario per esso (! Critsec). Lo stack per il thread proprietario ha un aspetto simile al seguente. L'ho tagliato per farla breve per questo post. (! Dumpstack)
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
È possibile utilizzare Debug Diag per analizzare il dump, in quanto può analizzare diversi schemi di deadlock più di sosex. Tuttavia, nessuno strumento automatico è in grado di identificare tutti i modelli, poiché a volte lo stallo è troppo complicato per essere compreso da un essere umano. Se puoi permetterti, apri un caso di supporto tramite http://support.microsoft.com per consultare Microsoft. –
@LexLi, grazie per il suggerimento Debug Diag. L'avevo già incontrato ma l'ho respinto perché sembrava essere troppo specifico per IIS. L'ho eseguito su uno dei precedenti mem dump ed è fondamentalmente sottolineando la stessa cosa: il thread GC in attesa di crit sec di proprietà di un altro thread. Che tipo di conferma mi dà lo stallo. Sembra che Debug Diag usi la stessa estensione psscor4. Inoltre stiamo esaminando anche l'opzione di supporto MS. Grazie! – user1210698
Penso che dovresti controllare tutte le implementazioni del finalizzatore (~). Sembra che tu stia bloccando definitivamente i tuoi finalizzatori – 6opuc