Cos'è LogHelp_TerminateOnAssert?

Nov 04 2020

C'è una domanda simile di un decennio fa, ma non c'era una buona risposta - si spera che le cose siano cambiate da allora.

Ho un'app Winforms abbastanza multithread basata su .NET 4.72. Lo sto guardando con la vista Process Explorer Threads e ha molte clr.dll!LogHelp_TerminateOnAssert+0x6835chiamate di tipo. Ho impostato il percorso dei simboli ma non mi è stato chiaro nulla.

Ho preso un dump dell'applicazione e l'ho eseguito tramite DebugDiag e WinDbg e non ho visto nulla di sospetto che risaltava.

Quindi le mie domande:

  • Dovrei preoccuparmi del gran numero di chiamate LogHelp_TerminateOnAssert?
  • L'applicazione perde memoria?
  • Presenta un numero eccessivo di eccezioni che non vengono filtrate quando eseguo l'app in Visual Studio?

L'unica voce dal mio codice qui è !get_FrameReceivede lo stack per quel thread è il seguente:

Lo stack per il thread con il maggior numero di cicli è così:

Risposte

2 ThomasWeller Nov 05 2020 at 21:01

Grandi offset

clr.dll!LogHelp_TerminateOnAssert+0x6835

significa che l'esecuzione effettiva in quel metodo è 0x6835 = 26661 byte di distanza dal suo inizio. È improbabile che un metodo sia così grande. (Come sottolinea @blabb, è un metodo a 1 byte).

Di solito lo vedi quando non hai impostato correttamente i simboli (come nella domanda originale collegata), ma hai risolto.

È probabile che Microsoft abbia rilasciato solo i simboli pubblici clr.dlle non quelli privati. In tal caso, vedrai solo l'ultimo metodo pubblico noto.

Indirizzo iniziale

Tieni presente che la colonna è denominata "Indirizzo iniziale". Process Explorer mostrerà la prima voce nello stack.

Quindi è qui che inizia tutto. Sembri preoccupato che sia qui che finisce tutto.

Nota: alcuni metodi interni noti come RtlUserThreadStarte BaseThreadInitThunkverranno ignorati durante la visualizzazione dell'indirizzo di partenza. Altrimenti probabilmente sarebbero tutti uguali.

Ciò che il thread sta realmente facendo è in cima alla lista, cioè ZwRemoveIoCompletion, quindi sembra che esegua alcune operazioni di I / O.

Le tue domande

Dovrei preoccuparmi del gran numero di chiamate LogHelp_TerminateOnAssert?

No. Questi sono solo il punto di partenza per qualcosa di buono. Le GetQueuedCompletionStatus()Sembra che ci sia un po 'di IO in corso e .NET utilizza le porte IO completamento (IOCP) per voi.

L'applicazione perde memoria?

Non lo capisci da uno sguardo agli stack di chiamate. Lo dici guardando la memoria nel tempo.

Se hai una quantità eccessiva di I / O di rete in corso e la rete non riesce a tenere il passo, .NET potrebbe avere sempre più elementi nella coda, quindi potrebbe sembrare una perdita di memoria.

Presenta un numero eccessivo di eccezioni che non vengono filtrate quando eseguo l'app in Visual Studio?

Non lo diresti nemmeno dallo stack di chiamate. Allegheresti un debugger (ad esempio WinDbg) e verifichi le eccezioni (come sxe clr), se non ti fidi di Visual Studio.

2 blabb Nov 05 2020 at 18:43

alla build del rilascio tutte queste affermazioni sono compilate in un semplice ret qualcosa di simile a

ifdef ( debug ) { function body here } elseif { ret } endif

quindi i simboli con un offset così grande sono falsi

quindi potrebbe essere necessario caricare i simboli effettivi per quell'indirizzo per un callstack ragionevole

puoi vedere la dimensione della funzione in clr 4.0.30319 clr.dll è solo 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