Teil 3.3 – Debugger, Kernabbilder und Sammeln von Kernabbildern
Gilt für: .NET Core 2.1, .NET Core 3.1, .NET 5
In diesem Artikel werden Debugger und Kernabbilder sowie die Tools zum Erfassen und Analysieren von Core-Abbilddateien in Linux vorgestellt.
Voraussetzungen
Wie in den vorherigen Teilenist dieser Teil strukturiert, um die zu befolgenden Prinzipien und Prinzipien zu berücksichtigen, wenn Sie mit der Problembehandlung beginnen. Es gibt keine Voraussetzungen. Sie sollten jedoch bereits die folgenden Elemente eingerichtet haben, wenn Sie alle Schritte dieser Schulung bisher ausgeführt haben:
- Nginx verfügt über zwei Websites:
- Die erste Website lauscht mithilfe des Hostheaders "myfirstwebsite" ( ) auf Anforderungen
http://myfirstwebsiteund leitet die Anforderungen an die Demo ASP.NET Core Anwendung weiter, die an Port 5000 lauscht. - Die zweite Website lauscht mithilfe des Hostheaders "jsamb ( ) " auf Anforderungen
http://buggyambund leitet die Anforderungen an die zweite ASP.NET Core Beispielanwendung weiter, die an Port 5001 lauscht.
- Die erste Website lauscht mithilfe des Hostheaders "myfirstwebsite" ( ) auf Anforderungen
- Beide ASP.NET Core Anwendungen werden als Dienste ausgeführt, die automatisch neu gestartet werden, wenn der Server neu gestartet wird oder die Anwendungen nicht mehr reagieren oder fehlschlagen.
- Eine lokale Linux-Firewall ist aktiviert und konfiguriert, um SSH- und HTTP-Datenverkehr zuzulassen.
Ziel dieses Teils
In diesem Teil werden das Konzept der Kernabbilder und Debugger sowie die Tools vorgestellt, die Sie zum Erfassen und Analysieren von Kernabbilddateien verwenden können. Die meisten der in diesem Teil beschriebenen Techniken und Tools werden in den nächsten Problembehandlungslaboren verwendet.
Coredump
Genau wie ein Speicherabbild im Benutzermodus in Windows ist ein Kernabbild eine Momentaufnahme des Speichers eines Prozesses. Kernabbilder sind häufig erforderlich, um Leistungsprobleme in Linux zu beheben.
Ein Kernabbild kann bei Bedarf von einem Debugger (manuelle Speicherabbildsammlung) generiert oder so konfiguriert werden, dass es nach einem Prozessfehler automatisch erfasst wird.
Was geschieht, wenn ein Prozess unter Linux fehlschlägt?
Die meisten Linux-Systeme verfügen über standardmäßig aktivierte Kernabbilder. Das System generiert ein Kernabbild für jeden Prozess, der unerwartet beendet wird. Dies ähnelt der Art und Weise, in der Windows-Fehlerberichterstattung (WER) Speicherabbilder für Prozesse generiert, die nicht normal beendet werden.
Hier sind einige wichtige Aspekte des Verhaltens eines Linux-Systems im Zusammenhang mit der Generierung von Kernabbilddateien:
- Standardmäßig wird eine Kernabbilddatei generiert, wenn ein Prozess unerwartet beendet wird.
- Die Core-Abbilddatei heißt "Core" und wird im aktuellen Arbeitsverzeichnis oder im /var/lib/systemd/coredump Verzeichnis erstellt.
- Obwohl das Standardverhalten für das Betriebssystem das Generieren einer Core-Abbilddatei ist, kann diese Einstellung überschrieben /proc/sys/kernel/core_pattern werden, um die Ausgabe der Kernabbilddatei direkt an eine andere Anwendung weiterzuleitung.
Diese Standardeinstellungen und einige andere Einstellungen, z. B. die Größenbeschränkungen, können in Konfigurationsdateien festgelegt werden. Die folgenden Ressourcen gehen ausführlicher auf dieses Thema ein:
Externer Link: Ubuntu Man Page Core – Kernabbilddatei
Apport: Ubuntus Methode zum Verwalten von Kernabbilddateien
In Ubuntu verwaltet der Apport-Systemdienst die Kernabbildgenerierung. Auch wenn die Core Dump-Generierung des Betriebssystems deaktiviert ist, erstellt apport weiterhin Kernabbilddateien.
Apport /proc/sys/kernel/core_pattern verwendet, um die Kernabbilddatei direkt an den Apport weiterzuleitung. Wenn Sie den cat /proc/sys/kernel/core_pattern Befehl ausführen, während apport ausgeführt wird, sollte das folgende Ergebnis angezeigt werden.
Wenn Sie apport deaktivieren, verhindert dies nicht die Generierung des Kernabbilds beim Beenden des Prozesses. Stattdessen wird der Apport einfach beendet. Das System wird dann auf sein Standardverhalten zurückgesetzt, indem Kernabbilder selbst generiert werden. Wenn Sie dieselbe Ausführung cat /proc/sys/kernel/core_pattern ausführen, nachdem der Apport beendet wurde, wird das folgende Standardsystemverhalten angezeigt.
Deaktivieren der automatischen Generierung von Kernabbild
Führen Sie die folgenden Schritte aus, um die automatische Generierung von Kernabbilddateien zu deaktivieren:
- Beenden und deaktivieren Sie apport.
- Deaktivieren Sie die Standardaktion des Systems.
Apport kann wie jeder andere Dienst beendet und deaktiviert werden. Verwenden Sie den sudo systemctl stop apport Befehl und den sudo systemctl disable apport Befehl, um den Dienst zu beenden, und deaktivieren Sie ihn, um zu verhindern, dass er neu gestartet wird.
Um die automatische Speicherabbilddateigenerierung des Betriebssystems für alle Prozesse zu deaktivieren, die unter allen Benutzerkonten auf dem Computer ausgeführt werden, müssen Sie die schritte ausführen, die in artikeln wie diesembereitgestellt werden.
Erfassen von Kernabbild- und Debuggern
Es stehen mehrere Tools zum Erfassen einer Zentralen Speicherabbilddatei zur Verfügung, z. B. gcore, gdb und mehrere Tools zum Analysieren einer Kernabbilddatei, z. B. Objdump, kdump, gdbund lldb.
Es treten jedoch einige erhebliche Schwierigkeiten auf, wenn Sie mit diesen Tools arbeiten, um zu versuchen, .NET-Debugging auszuführen:
- Die Konfiguration kann im Vergleich zum Einrichten von Symbolen für den WinDbg-Debugger auf Windows schwierig sein.
- Kernabbilddateien sind groß, da diese Tools nicht wissen, welcher Speicherbereich in einem .NET Core-Prozess verwendet wird, und sie können die Speicherinformationen nicht auf die erforderlichen Elemente kürzen.
- Speicherabbilddateien sind nicht portierbar. Sie müssen die Abbilddateien auf dem Linux-Computer analysieren, auf dem sie generiert wurden. Wenn Sie die Abbilddateien auf einem anderen Linux-Computer analysieren möchten, sind zusätzliche Schritte erforderlich, um den Hostcomputer für die Debugsitzung zu konfigurieren.
lldb
Lldb ist das empfohlene Tool zum Analysieren des .NET Core-Abbilds. Das .NET SDK enthält nützliche Tools zum ordnungsgemäßen Konfigurieren von lldb. Sie müssen jedoch mindestens Version 3.9 installieren, um eine solche Debuganalyse für .NET Core durchführen zu können.
Um lldb 3.9 oder eine höhere Version zu installieren, verwenden Sie Paket-Manager (z. B.: sudo apt install lldb ).
Tools und Befehle, die in der .NET Core-Laufzeit und im SDK verfügbar sind
In der .NET Core-Laufzeit sind mehrere nützliche Tools enthalten. Wird beispielsweise createdump als Teil jeder Laufzeitinstallation von .NET Core installiert.
Sie können auch eigene Tools entwickeln oder mehrere Drittanbietertools verwenden. Die Microsoft .NET Core-Plattform enthält auch einige .NET Core-Tools, die zum Debuggen von .NET Core-Problemen hilfreich sind. Hierzu gehören:
- dotnet-dump
- dotnet-gcdump
- Dotnet-Symbol
Um diese Tools zusammen mit den anderen Tools zu installieren, muss .NET Core SDK installiert sein. Weitere Informationen zum .NET Core SDK finden Sie unter: .NET SDK Overview.
Hinweis
Procdump ist auch eine Erwähnung, obwohl es nicht Teil des SDK ist. Eine ausführliche Erläuterung der ProcDump-Optionen finden Sie am Ende dieses Teils.
createdump
Createdump wird in jeder .NET Core-Version installiert. Weitere Informationen finden Sie in den Implementierungsdetails.
Createdump ist die beste Möglichkeit, um eine Core-Abbilddatei in Linux zu generieren. Dies liegt daran, dass die automatisch vom System generierten Abbilddateien möglicherweise nicht alle verwalteten Zustände enthalten. Außerdem können einige SOS- oder Dotnet-Dumpbefehle für Typ- und Funktionsnamen "UNKNOWN" anzeigen.
Ebenso enthalten die manuellen Abbilddateien, die mithilfe von gdb oder gcore erstellt werden, nicht alle Informationen zum verwalteten Zustand, und einige SOS- oder Dotnet-Dump-Befehle zeigen möglicherweise auch "UNKNOWN" für Typ- und Funktionsnamen an. Die empfohlene Methode zum Erfassen manueller Abbilddateien ist die Verwendung von createdump oder eines anderen .NET Core-Tools, z. B. Procdump.
Hier sind einige wichtige Features von createdump:
- Minidumps mit minimaler Größe werden automatisch generiert.
- Die Konfiguration mit einem Nicht-Stammbenutzer ist einfach.
- Sie können es verwenden, um Abbilddateien für Bedarfsabbilder (manuell) oder Systemfehler zu erfassen.
- Die meisten Stapelüberlauffehler werden erkannt.
Sie müssen lldb 3.9 oder eine höhere Version verwenden, um die zentralen Abbilddateien zu analysieren, die mithilfe von createdump erfasst werden.
Createdump finden Sie im .NET Core-Installationsverzeichnis. Führen Sie den Befehl aus, um dieses Verzeichnis zu dotnet --list-runtimes finden. Wie im folgenden Screenshot gezeigt, wurde eine separate createdump-Datei für die beiden Versionen der aktiven Laufzeiten erstellt.
dotnet-dump
Sie müssen .NET Core SDK installiert haben, um dieses Tool installieren zu können. Dotnet-Dump wurde im .NET Core 3.0 SDK eingeführt. Es hilft bei der Erfassung und Analyse von Kernabbilddateien, ohne dass ein systemeigener Debugger erforderlich ist. Sie können SOS-Befehle ausführen, um Fehler und die Gc-Ausgabe (Garbage Collector) zu analysieren.
Hinweis
Dotnet-Dump ist kein systemeigener Debugger. Daher sind einige Features, z. B. das Anzeigen der nativen Stapelframes, nicht verfügbar. Die generierte Abbilddatei ist nicht portierbar, und Sie können sie nicht in Windows öffnen.
Führen Sie den folgenden Befehl aus, um dieses Tool zu installieren:
dotnet tool install -g dotnet-dump
Mit diesem Tool können Sie die wichtigsten Abbilddateien in den kommenden Übungsabschnitten erfassen und analysieren.
dotnet-gcdump
Dies ist ein weiteres Tool, das .NET Core SDK erfordert. Dotnet-gcdump ist in .NET Core 3.1 oder höher verfügbar.
Dies ist ein interessanter Ansatz für die Analyse von GC-Heaps. Die Idee hinter diesem Tool ist, dass für Untersuchungen in vielen Szenarien keine vollständige Prozessabbilddatei erforderlich ist. Daher erfasst das Tool nur die verwalteten Heap-Informationen und generiert einen darauf basierenden Bericht.
Am wichtigsten ist, dass die von diesem Tool generierten Abbilddateien portierbar sind und in PerfView oder Visual Studio in Windows analysiert werden können.
Wie hierkurz erläutert wird, wird von diesem Tool eine vollständige Garbage Collection ausgelöst, um die Informationen an eine "Ereignispipe" zu streamen, um die Speicherabbilddatei zu generieren.
Hinweis
Da eine vollständige Gen 2-Garbage Collection im Zielprozess ausgelöst wird, können die Leistungsmerkmale der Anwendung geändert werden. Wie Sie vielleicht erwarten, werden die Threads angehalten, während die Informationen in die Kernabbilddatei geschrieben werden. Je größer die Heapgröße, desto länger sind die Pausen, um die Informationen in die Datei zu schreiben, und je länger die Threads angehalten bleiben.
Die Informationen, die in solchen Kernabbilddateien enthalten sind, sind unter den folgenden Umständen nützlich:
- Vergleichen der Anzahl der Objekte nach Typ auf dem verwalteten Heap
- Analysieren von Objektstamm
- Bestimmen, welche Objekte einen Verweis auf welchen Typ haben
- Andere statistische Analysen zu Objekten auf dem Heap
Nachdem die Daten generiert wurden, kann die Datei außerhalb des Computers exportiert werden, auf dem sie erstellt wurde, und sie kann in PerfView oder in Visual Studio analysiert werden.
Führen Sie den folgenden Befehl aus, um dieses Tool zu installieren:
dotnet tool install -g dotnet-gcdump
Sie werden diesen Befehl verwenden, um einige Berichte für .NET Core-Heaps in den kommenden Übungsabschnitten zu generieren.
Dotnet-Symbol
Das Dotnet-Symbol ist ein nützliches Tool zum Abrufen von Symbolen für das verwaltete Debuggen. Es wurde in .NET Core 2.1 eingeführt. Wie bei den beiden anderen tools, die bereits erwähnt werden, müssen diese Tools auch .NET Core SDK installiert werden.
Dotnet-symbol lädt alle Dateien herunter, die für das Debuggen (Symbole, Module, SOS und DAC für das Coreclr-Modul) für alle core-Abbilddateien benötigt werden.
Führen Sie den folgenden Befehl aus, um dieses Tool zu installieren:
dotnet tool install -g dotnet-symbol
Sie verwenden dieses Tool, um den Debugger in den kommenden Übungsabschnitten zu konfigurieren.
procdump
Eine Linux-Version von ProcDump ist ebenfalls verfügbar. Es verfügt über einige eingeschränkte Featuresätze im Vergleich zu seinem Windows Gegenstück. Es unterstützt nicht jedes Feature, das die Windows Version hat. Sie kann z. B. nicht so konfiguriert werden, dass Kernabbilddateien erfasst werden, wenn der Prozess abstürzt oder eine Ausnahme mit der ersten Chance auslöst. Es ist jedoch immer noch ein leistungsfähiges Tool.
Die folgenden Befehlszeilenoptionen für ProcDump lösen die Generierung von Kernabbilddateien unter den angegebenen Bedingungen aus.
-C: CPU exceeds or equals a specified value (0 to 100 * nCPU)
-c: CPU is less than a specified value (0 to 100 * nCPU)
-M: The memory commit exceeds or equals a specified value (MB)
-m: The memory commit is less than a specified value (MB)
-T: The thread count exceeds or equals a specified value
-F: The filedescriptor count exceeds or equals a specified value
Befolgen Sie die Installationsanweisungen, um ProcDump in Ihrer Umgebung zu installieren.
Sie verwenden dieses Tool, um eine zentrale Speicherabbilddatei zu erfassen, die auf der CPU-Auslastung in den kommenden Übungsabschnitten basiert.
Hinweis zur Auswahl der SDK-Version
Standardmäßig wird das SDK in einer "Parallel"-Konfiguration installiert. Dies bedeutet, dass mehrere Versionen gemeinsam auf einem einzelnen Computer ausgeführt werden können. Wie die Version beim Ausführen von CLI-Befehlen ausgewählt wird, wird im Artikel "Auswählen der .NET Core-Version zur Verwendung" ausführlicher erläutert. Der Prozess für die Auswahl einer SDK-Version kann jedoch wie folgt zusammengefasst werden:
- .NET Core sucht iterativ nach einer "global.json"-Datei und navigiert den Pfad aus dem aktuellen Arbeitsverzeichnis nach oben.
- .NET Core verwendet das SDK, das in der ersten gefundenen "global.json" angegeben ist.
- .NET Core verwendet das neueste installierte SDK, wenn keine global.json-Instanz gefunden wird.
Beispielsweise sollten auf dem virtuellen Linux-Testcomputer sowohl die .NET Core 3.1- als auch die 5.0-SDKs installiert sein. Wenn Sie .NET Core ausführen, indem Sie den --version Switch einschließen, sollten Sie sehen, dass die neueste Version verwendet wird.
Erstellen Sie nun eine datei global.json im aktuellen Verzeichnis (Ihr Startverzeichnis), und legen Sie die Version wie dargestellt explizit mithilfe des Cat-Tools fest. Überprüfen Sie dann die Version erneut. Jetzt wird die genaue SDK-Version angezeigt, die Sie in die Datei "global.json" eingefügt haben.
Dies ist wichtig, wenn Sie einige SDK-Befehle ausführen, z. B. das Erstellen einer Anwendung mithilfe des .NET new Core-Befehls. Sie müssen dies jedoch nicht tun, wenn Sie die Dotnet-Dump- und dotnet-gcdump-Tools verwenden.
.NET Core SDK installiert die neueste Version der Tools, unabhängig davon, welches SDK Sie ausgewählt haben. Wenn Sie beispielsweise die Befehle zum Installieren des Dotnet-Dump-, Dotnet-GCDUMP- und Dotnetsymboltools für .NET Core SDK 3.1 ausgeführt haben, werden die neuesten Versionen dieser Tools heruntergeladen und installiert, wie im folgenden Screenshot dargestellt (in dem Version 5 der Tools für dotnet-dump und dotnet-gcdump installiert wurde).
Die folgenden Artikel sind großartige Ressourcen für weitere Informationen zu .NET Core-Tools:
Hinweis
Das Auswählen der zu verwendenden Laufzeitversion unterscheidet sich von der Auswahl der SDK-Version. Wenn Sie eine bestimmte Version der .NET-Laufzeit verwenden möchten, verwenden Sie die Option --fx-version, <VERSION> wie in diesem Artikelerläutert.
Nächste Schritte
Jetzt können Sie mit den Problembehandlungslaboren beginnen. In den Laboren erfahren Sie, wie Sie die hier beschriebenen Tools verwenden, um Probleme zu beheben.