Was ist LogHelp_TerminateOnAssert?

Nov 04 2020

Es gibt eine ähnliche Frage von vor einem Jahrzehnt, aber es gab keine gute Antwort - hoffentlich haben sich die Dinge seitdem geändert.

Ich habe eine ziemlich multithreaded Winforms App basierend auf .NET 4.72. Ich betrachte es mit der Ansicht "Prozess-Explorer-Threads" und es gibt viele clr.dll!LogHelp_TerminateOnAssert+0x6835Typaufrufe. Ich habe den Symbolpfad eingerichtet, aber er hat mir nichts wirklich klar gemacht.

Ich habe einen Dump der Anwendung erstellt und sie über DebugDiag und WinDbg ausgeführt und nichts Verdächtiges gesehen, das auffiel.

Also meine Fragen:

  • Sollte ich mich mit der großen Anzahl von LogHelp_TerminateOnAssert-Aufrufen befassen?
  • Verliert die Anwendung Speicher?
  • Gibt es zu viele Ausnahmen, die beim Ausführen der App in Visual Studio nicht herausgefiltert werden?

Der einzige Eintrag aus meinem Code hier ist !get_FrameReceivedund der Stapel für diesen Thread ist wie folgt:

Der Stapel für den Thread mit den meisten Zyklen lautet wie folgt:

Antworten

2 ThomasWeller Nov 05 2020 at 21:01

Große Offsets

clr.dll!LogHelp_TerminateOnAssert+0x6835

bedeutet, dass die tatsächliche Ausführung in dieser Methode 0x6835 = 26661 Byte von ihrem Anfang entfernt ist. Es ist unwahrscheinlich, dass eine Methode so groß ist. (Wie @blabb hervorhebt, handelt es sich um eine 1-Byte-Methode).

Normalerweise sehen Sie das, wenn Sie die Symbole nicht richtig eingerichtet haben (wie in der verknüpften Originalfrage), aber Sie haben das behoben.

Möglicherweise hat Microsoft nur die öffentlichen clr.dllund nicht die privaten Symbole veröffentlicht . In diesem Fall wird nur die letzte bekannte öffentliche Methode angezeigt.

Startadresse

Bitte beachten Sie, dass die Spalte "Startadresse" heißt. Der Prozess-Explorer zeigt den ersten Eintrag auf dem Stapel an.

Hier fängt also alles an. Sie scheinen besorgt zu sein, dass hier alles endet.

Hinweis: Einige bekannte interne Methoden wie RtlUserThreadStartund BaseThreadInitThunkwerden beim Anzeigen der Startadresse übersprungen. Sonst würden sie wahrscheinlich alle gleich aussehen.

Was der Thread wirklich tut, steht ganz oben auf der Liste, dh ZwRemoveIoCompletioner scheint eine E / A-Operation auszuführen.

Deine Fragen

Sollte ich mich mit der großen Anzahl von LogHelp_TerminateOnAssert-Aufrufen befassen?

Nein, dies ist nur der Ausgangspunkt für etwas Gutes. Es GetQueuedCompletionStatus()sieht so aus, als ob einige E / A-Vorgänge stattfinden und .NET IOP (IO Completion Ports) für Sie verwendet.

Verliert die Anwendung Speicher?

Das erkennt man nicht an einem Blick auf Call Stacks. Sie erkennen dies, indem Sie die Erinnerung im Laufe der Zeit betrachten.

Wenn zu viele Netzwerk-E / A-Vorgänge ausgeführt werden und das Netzwerk nicht mithalten kann, befinden sich in .NET möglicherweise immer mehr Elemente in der Warteschlange, sodass es möglicherweise wie ein Speicherverlust aussieht .

Gibt es zu viele Ausnahmen, die beim Ausführen der App in Visual Studio nicht herausgefiltert werden?

Das würden Sie auch nicht vom Aufrufstapel unterscheiden. Sie würden einen Debugger (z. B. WinDbg) anhängen und nach Ausnahmen (wie sxe clr) suchen , wenn Sie Visual Studio nicht vertrauen.

2 blabb Nov 05 2020 at 18:43

Beim Release-Build werden alle diese Asserts zu einem einfachen Ret kompiliert, das dem ähnelt

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

Die Symbole mit dem großen Versatz sind also falsch

Daher müssen Sie möglicherweise die tatsächlichen Symbole für diese Adresse laden, um einen sinnvollen Callstack zu erhalten

Sie können die Größe der Funktion in clr 4.0.30319 sehen. clr.dll ist nur 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