¿Qué es LogHelp_TerminateOnAssert?
Hay una pregunta similar de hace una década, pero no hubo una buena respuesta; con suerte, las cosas han cambiado desde entonces.
Tengo una aplicación Winforms bastante multiproceso basada en .NET 4.72. Lo estoy viendo con la vista Process Explorer Threads y tiene muchas clr.dll!LogHelp_TerminateOnAssert+0x6835llamadas de tipo. Configuré la ruta de los símbolos, pero realmente no me aclaró nada.
Tomé un volcado de la aplicación y la ejecuté a través de DebugDiag y WinDbg y no vi nada sospechoso que se destacara.
Entonces mis preguntas:
- ¿Debería preocuparme por la gran cantidad de llamadas LogHelp_TerminateOnAssert?
- ¿La aplicación pierde memoria?
- ¿Tiene un número excesivo de excepciones que no se filtran cuando ejecuto la aplicación en Visual Studio?
La única entrada de mi código aquí es !get_FrameReceivedy la pila para ese hilo es la siguiente:
La pila del hilo con más ciclos es la siguiente:
Respuestas
Grandes compensaciones
clr.dll!LogHelp_TerminateOnAssert+0x6835
significa que la ejecución real en ese método es 0x6835 = 26661 bytes desde su comienzo. Es poco probable que un método sea tan grande. (Como señala @blabb, es un método de 1 byte).
Por lo general, lo ve cuando no ha configurado los símbolos correctamente (como en la pregunta original vinculada), pero lo ha solucionado.
Lo más probable es que Microsoft solo haya publicado los símbolos públicos clr.dlly no los privados. En ese caso, solo verá el último método público conocido.
Dirección de inicio
Tenga en cuenta que la columna se llama "Dirección de inicio". Process Explorer mostrará la primera entrada en la pila.
Entonces aquí es donde comienza todo. Parece estar preocupado de que aquí es donde todo termina.
Nota: algunos métodos internos conocidos como RtlUserThreadStarty BaseThreadInitThunkse omitirán al mostrar la dirección de inicio. De lo contrario, probablemente todos se verían iguales.
Lo que realmente está haciendo el hilo está en la parte superior de la lista, es decir ZwRemoveIoCompletion, parece que realiza alguna operación IO.
Tus preguntas
¿Debería preocuparme por la gran cantidad de llamadas LogHelp_TerminateOnAssert?
No. Estos son solo el punto de partida para algo bueno. Los GetQueuedCompletionStatus()Parece que hay alguna IO pasando y .NET utiliza los puertos IO Completion (IOCP) para usted.
¿La aplicación pierde memoria?
Eso no se nota al mirar las pilas de llamadas. Eso lo dices mirando la memoria a lo largo del tiempo.
Si tiene demasiada E / S de red activa y la red no puede seguirle el ritmo, .NET puede tener más y más elementos en la cola, por lo que puede parecer una pérdida de memoria.
¿Tiene un número excesivo de excepciones que no se filtran cuando ejecuto la aplicación en Visual Studio?
Tampoco lo diría de la pila de llamadas. Debería adjuntar un depurador (por ejemplo, WinDbg) y buscar excepciones (como sxe clr), si no confía en Visual Studio.
en la compilación de lanzamiento, todas estas afirmaciones se compilan en un simple ret, algo similar a
ifdef ( debug ) { function body here } elseif { ret } endif
por lo que los símbolos con un desplazamiento tan grande son falsos
por lo que es posible que deba cargar los símbolos reales para esa dirección para una pila de llamadas sensible
puede ver el tamaño de la función en clr 4.0.30319 clr.dll es 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