O que é LogHelp_TerminateOnAssert?
Há uma pergunta semelhante de uma década atrás, mas não houve uma boa resposta - espero que as coisas tenham mudado desde então.
Eu tenho um aplicativo Winforms bastante multithread baseado no .NET 4.72. Eu estou olhando para ele com o modo de exibição Threads do Process Explorer e ele tem muitas clr.dll!LogHelp_TerminateOnAssert+0x6835chamadas de tipo. Eu configurei o caminho de símbolos, mas realmente não esclareceu nada para mim.
Peguei um dump do aplicativo e o executei no DebugDiag e WinDbg e não vi nada suspeito que se destacasse.
Então, minhas perguntas:
- Devo me preocupar com o grande número de chamadas LogHelp_TerminateOnAssert?
- O aplicativo está perdendo memória?
- Ele tem um número excessivo de exceções que não são filtradas quando estou executando o aplicativo no Visual Studio?
A única entrada do meu código aqui é !get_FrameReceivede a pilha para esse thread é a seguinte:
A pilha para o encadeamento com mais ciclos é assim:
Respostas
Deslocamentos grandes
clr.dll!LogHelp_TerminateOnAssert+0x6835
significa que a execução real desse método está a 0x6835 = 26661 bytes de distância de seu início. É improvável que um método seja tão grande. (Como @blabb aponta, é um método de 1 byte).
Geralmente, você vê isso quando não configurou os símbolos corretamente (como na pergunta original vinculada), mas corrigiu isso.
Provavelmente, a Microsoft lançou apenas os símbolos públicos clr.dlle não os privados. Nesse caso, você verá apenas o último método público conhecido.
Endereço inicial
Observe que a coluna é chamada de "Endereço inicial". O Process Explorer mostrará a primeira entrada na pilha.
Então é aqui que tudo começa. Você parece estar preocupado porque é aqui que tudo termina.
Nota: alguns métodos internos conhecidos, como RtlUserThreadStarte BaseThreadInitThunk, serão ignorados ao exibir o endereço inicial. Caso contrário, eles provavelmente seriam todos iguais.
O que o encadeamento realmente está fazendo está no topo da lista, ou seja ZwRemoveIoCompletion, parece fazer alguma operação de E / S.
Suas perguntas
Devo me preocupar com o grande número de chamadas LogHelp_TerminateOnAssert?
Não. Esses são apenas o ponto de partida para algo bom. Os GetQueuedCompletionStatus()parece que há alguns IO acontecendo e .NET usa as portas IO conclusão (IOCP) para você.
O aplicativo está perdendo memória?
Você não percebe isso olhando as pilhas de chamadas. Você diz isso olhando para a memória ao longo do tempo.
Se você tiver muito IO de rede em execução e a rede não conseguir acompanhá-lo, o .NET pode ter cada vez mais itens na fila, então pode parecer um vazamento de memória.
Ele tem um número excessivo de exceções que não são filtradas quando estou executando o aplicativo no Visual Studio?
Você também não perceberia isso na pilha de chamadas. Você deve anexar um depurador (por exemplo, WinDbg) e verificar se há exceções (como sxe clr), se não confiar no Visual Studio.
na versão de lançamento, todas essas declarações são compiladas em um arquivo simples, algo semelhante a
ifdef ( debug ) { function body here } elseif { ret } endif
então os símbolos com grande deslocamento são falsos
então você pode precisar carregar os símbolos reais desse endereço para uma pilha de chamadas sensata
você pode ver o tamanho da função em clr 4.0.30319 clr.dll é de apenas 1 byte
0:000> x /v /t clr!LogHelp_TerminateOnAssert
pub func 100115a0 0 <NoType> clr!LogHelp_TerminateOnAssert (<no parameter info>)
0:000> .fnent clr!LogHelp_TerminateOnAssert
Debugger function entry 01bad5e0 for:
(100115a0) clr!RtlUnwindCallback | (100115a1) clr!memset
Exact matches:
clr!RtlUnwindCallback (void)
clr!_TlgDefineProvider_annotation__Tlgg_hClrProviderProv (void)
OffStart: 000115a0
ProcSize: 0x1
Prologue: 0x0
Params: 0n0 (0x0 bytes)
Locals: 0n0 (0x0 bytes)
Registers: 0n0
0:000> u clr!LogHelp_TerminateOnAssert l1
clr!RtlUnwindCallback:
100115a0 c3 ret