O que é LogHelp_TerminateOnAssert?

Nov 04 2020

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

2 ThomasWeller Nov 05 2020 at 21:01

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.

2 blabb Nov 05 2020 at 18:43

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