Pergunta

Eu tenho um serviço do Windows .NET multithread que trava intermitentemente - talvez uma vez a cada duas semanas de operação 24/7. Quando os trava ocorre o pool de threads está completamente saturado, porque as chamadas para o nosso TraceListener costume começar a bloquear por algum motivo. Não existem bloqueios no código ofensivo nem nada bloqueando acordo com windbg, mas eles estão bloqueando definitivamente em algum lugar. Não existem exceções na pilha também. Há uma Thread.Sleep (1) que irá, eventualmente, ser atingido no código BufferedStream.Write, mas a minha pergunta é qual é a ReOpenMetaDataWithMemory, CreateApplicationContext e DllCanUnloadNow média?

Quase todos os 2.000 desligou segmentos de trabalho (não operação normal!) No ThreadPool tem uma pilha semelhante à seguinte:

0:027> !dumpstack
OS Thread Id: 0x1638 (27)
Child-SP         RetAddr          Call Site
000000001d34df58 0000000077d705d6 ntdll!ZwDelayExecution+0xa
000000001d34df60 000006427f88901d kernel32!SleepEx+0x96
000000001d34e000 000006427f454379 mscorwks!DllCanUnloadNowInternal+0xf53d
000000001d34e080 000006427fa34749 mscorwks!CreateApplicationContext+0x41d
000000001d34e0e0 0000064280184902 mscorwks!ReOpenMetaDataWithMemory+0x1ff59
000000001d34e290 0000064280184532 Company_Common_Diagnostics!Company.Common.Diagnostics.BufferedStream.Write(Byte[], Int32, Int32)+0x1b2
000000001d34e300 00000642801831fd Company_Common_Diagnostics!Company.Common.Diagnostics.XmlRollingTraceListener+TraceWriter.Write(System.String)+0x52
000000001d34e350 00000642801b3304 Company_Common_Diagnostics!Company.Common.Diagnostics.XmlRollingTraceListener.InternalWrite(System.Text.StringBuilder)+0x3d
000000001d34e390 0000064274e9d7ec Company_Common_Diagnostics!Company.Common.Diagnostics.XmlRollingTraceListener.TraceTransfer(System.Diagnostics.TraceEventCache, System.String, Int32, System.String, System.Guid)+0xc4
000000001d34e410 00000642801b2f59 System_ni!System.Diagnostics.TraceSource.TraceTransfer(Int32, System.String, System.Guid)+0x2ec
Foi útil?

Solução 4

Descobri-lo eu acredito. Entrei no BufferStream e viu que estava em um estado onde qualquer coisa que chamou para o TraceListener seria apenas ficar preso em um (1) loop de Thread.Sleep. Espero que esta é a correção porque eu não posso para a vida de me recriar o problema.

Eu tive usegloballock = false e autoflush = true na configuração de rastreio. O método flush no TraceListener não era thread-safe - o ouvinte se destina a buffer uso de dados, de modo que na ocasião o TraceListener iria ficar em mau estado quando não havia concorrência de liberações e escreve. A correção foi simplesmente conjunto autoflush = false. Eu não posso acreditar que eu não pegar isso mais cedo.

Outras dicas

Não é realmente uma resposta, mas algo para verificar ...

Certifique-se que você não ainda tem a DefaultTraceListener registrado em seu fonte de rastreamento. Se você não fizer isso explicitamente clara ou Remover DefaultTraceListener pode ainda estar lá. O DefaultTraceListener 's IsThreadSafe propriedade retorna false , caso em que as classes System.Diagnostics.Trace criar um lock () em torno da TraceEvent () chamadas ..

Apenas algo que atente para.

Mais informações:

TraceListener.IsThreadSafe Propriedade

O valor da IsThreadSafe é usado para determinar se deve usar um bloqueio global ao escrever para o ouvinte. Se o valor da IsThreadSafe é falsa, o bloqueio global é usado independentemente do valor de UseGlobalLock. O bloqueio global não é usado somente se o valor de IsThreadSafe é verdadeiro e o valor de UseGlobalLock é falsa. O comportamento padrão é usar o bloqueio global sempre escrevendo para o ouvinte.

Obrigado, Aaron

O fato de deslocamento para estas funções parecem maneira de grandes (mscorwks! ReOpenMetaDataWithMemory + 0x1ff59), eu vou dizer que você não tem símbolos para mscorwks.

Definir uma loja local símbolo usando:

.symfix + c: \ websymbols
.reload mscorwks.dll
onde c: \ websymbols é um caminho de sua escolha para símbolos do sistema. Isso deve lhe dar os nomes das funções razoáveis ??onde kernel32! Sono é chamado a partir.

Quanto ao resto, o que faz uma pilha para todos os outros tópicos até pendurados parece? Além disso, você pode postar uma pilha nativa (kb) assim?

Você está certo.

Existem cerca de 2000 desligou tópicos e o rastreamento de pilha sobre eles é quase idêntico. Há uma função KeepAlive no código que dings cada 1 segundo. Há uma monitor.tryenter em torno do código ding. Se ele não pode adquirir o bloqueio emite um traço. Isso é o que todos esses tópicos estão fazendo. O segmento que possui o bloqueio (18) tem o mesmo rastreamento de pilha praticamente.

Existe uma maneira de ver as variáveis ??locais na classe BufferedStream para ver se ele está preso em um loop?

0:047> kb
RetAddr           : Args to Child                                                           : Call Site
00000000`77d705d6 : ffffffff`fffffffe 00000000`00000000 00000000`00000000 00000000`1ef7f160 : ntdll!ZwDelayExecution+0xa
00000642`7f88901d : 00000000`00000029 00000642`00000001 00000000`00000000 00000000`1c00f820 : kernel32!SleepEx+0x96
00000642`7f454379 : 00000000`00c70128 00000642`7fa2b159 00000000`00000001 00000000`00000001 : mscorwks!EESleepEx+0x2d
00000642`7fa34749 : 06000000`00000001 00000000`1c00f820 00000000`00c6ff08 00000000`00000001 : mscorwks!Thread::UserSleep+0x71
00000642`80184902 : 00000000`00000001 00000642`782f1950 00000000`015695e0 00000000`00000000 : mscorwks!ThreadNative::Sleep+0xf9
00000642`80184532 : 00000000`00c6fe90 00000642`783924e2 00000000`00db11d8 00000000`00000008 : 0x642`80184902
00000642`801831fd : 00000000`00c6fe90 00000000`00000008 00000642`80043680 00000000`00c02d58 : 0x642`80184532
00000642`74e9e494 : ffffffff`fffffffe 00000000`00000001 0000c0c9`0263a71f 00000642`7f361300 : 0x642`801831fd
00000642`8018d3d3 : 00000000`00c02d58 00000000`00000008 00000000`00000000 00000000`00db11d8 : System_ni+0x61e494
00000642`782f173b : 00000000`00c036a0 00000642`7834901c 00000642`78431598 00000000`77ef9971 : 0x642`8018d3d3
00000642`7834d696 : 00000000`00a061b0 00000000`00400080 00000000`00000000 00000642`7f529408 : mscorlib_ni+0x2f173b
00000642`7f602672 : 00000000`00db0cb8 000007ff`7d370000 000007ff`7d370000 000007ff`fffdb000 : mscorlib_ni+0x34d696
00000642`7f50c053 : 00000642`7f39f3f6 00000000`77dbc178 00000000`00000000 00000000`00000000 : mscorwks!CallDescrWorker+0x82
00000642`7f51449a : 00000000`1ef7f9f8 ffffffff`fffffffe 00000000`00000000 00000000`77d6f447 : mscorwks!CallDescrWorkerWithHandler+0xd3
00000642`7f46b023 : 00000000`00000001 00000000`77d6f491 00000000`00000000 00000000`1ee81000 : mscorwks!DispatchCallDebuggerWrapper+0x3e
00000642`7f41729e : 00000000`1ef7fb88 00000000`1c00f801 00000000`00000001 00000000`1c00f820 : mscorwks!DispatchCallNoEH+0x5f
00000642`7f447ee8 : 00000000`00db0cb8 00000000`00db0cb8 00000000`00000001 00000642`7f50946a : mscorwks!AddTimerCallback_Worker+0x92
00000642`7f556aa9 : 00000000`00000001 00000000`00000000 ffffffff`fffffffe 00000000`1ef7fba8 : mscorwks!Thread::DoADCallBack+0x488
00000642`7f43afdd : 00000000`001597d0 00000000`1c00f820 00000000`1ef7fab0 00000000`0019fcb0 : mscorwks!CNgenEntryBind::Create+0x15d
00000642`7f435296 : 00000000`1ef7fba8 ffffffff`ffffffff 00000000`1c00f820 00000642`7f885bdb : mscorwks!MethodTable::IsAbstract+0x49
0:047> !dumpstack
OS Thread Id: 0x15b0 (47)
Child-SP         RetAddr          Call Site
000000001ef7f138 0000000077d705d6 ntdll!ZwDelayExecution+0xa
000000001ef7f140 000006427f88901d kernel32!SleepEx+0x96
000000001ef7f1e0 000006427f454379 mscorwks!EESleepEx+0x2d
000000001ef7f260 000006427fa34749 mscorwks!Thread::UserSleep+0x71
000000001ef7f2c0 0000064280184902 mscorwks!ThreadNative::Sleep+0xf9
000000001ef7f470 0000064280184532 Company_Common_Diagnostics!Company.Common.Diagnostics.BufferedStream.Write(Byte[], Int32, Int32)+0x1b2
000000001ef7f4e0 00000642801831fd Company_Common_Diagnostics!Company.Common.Diagnostics.XmlRollingTraceListener+TraceWriter.Write(System.String)+0x52
000000001ef7f530 0000064274e9e494 Company_Common_Diagnostics!Company.Common.Diagnostics.XmlRollingTraceListener.InternalWrite(System.Text.StringBuilder)+0x3d
000000001ef7f570 000006428018d3d3 System_ni!System.Diagnostics.TraceSource.TraceEvent(System.Diagnostics.TraceEventType, Int32, System.String)+0x2b4
000000001ef7f620 00000642782f173b Company_Common_Routing_Service!Company.Common.RouterService.KeepAlive(System.Object)+0x2a3
000000001ef7f6f0 000006427834d696 mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0x9b
000000001ef7f740 000006427f602672 mscorlib_ni!System.Threading._TimerCallback.PerformTimerCallback(System.Object)+0x86
000000001ef7f790 000006427f50c053 mscorwks!CallDescrWorker+0x82
000000001ef7f7e0 000006427f51449a mscorwks!CallDescrWorkerWithHandler+0xd3
000000001ef7f880 000006427f46b023 mscorwks!DispatchCallDebuggerWrapper+0x3e
000000001ef7f8e0 000006427f41729e mscorwks!DispatchCallNoEH+0x5f
000000001ef7f960 000006427f447ee8 mscorwks!AddTimerCallback_Worker+0x92
000000001ef7f9f0 000006427f556aa9 mscorwks!Thread::DoADCallBack+0x488
000000001ef7fa40 000006427f43afdd mscorwks!CNgenEntryBind::Create+0x15d
000000001ef7fb10 000006427f435296 mscorwks!MethodTable::IsAbstract+0x49
000000001ef7fb50 000006427f4162bb mscorwks!AddTimerCallbackEx+0xba
000000001ef7fc10 000006427f495fa7 mscorwks!ThreadpoolMgr::AsyncTimerCallbackCompletion+0x53
000000001ef7fc70 000006427f4aad0a mscorwks!UnManagedPerAppDomainTPCount::DispatchWorkItem+0x157
000000001ef7fd10 000006427f41f9a0 mscorwks!ThreadpoolMgr::WorkerThreadStart+0x1ba
000000001ef7fdb0 0000000077d6b6da mscorwks!Thread::intermediateThreadProc+0x78
000000001ef7ff80 0000000000000000 kernel32!BaseThreadStart+0x3a
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top