Core-Dumps auf dem Dedicated Server erfassen und auswerten
Wenn ein Anwendungsprozess plötzlich beendet wird, stellt ein Neustart des Dienstes den Betrieb wieder her, erklärt aber nicht die Absturzursache. Enthalten die Protokolle lediglich eine Signalnummer, werden für die Diagnose zusätzlich der Aufruf-Stack zum Absturzzeitpunkt und der zugehörige Build benötigt. Diese Anleitung richtet unter Ubuntu Server 24.04 eine kontrollierte Erfassungskette für Core-Dumps ein. Zunächst wird sie mit einem isolierten Prozess geprüft; erst danach wird entschieden, ob sie für einen produktiven Dienst aktiviert werden soll.
Dedicated Server von AMDSSH sind mit 128GB oder 256GB ECC-Arbeitsspeicher verfügbar. Prozess-Dumps sollten jedoch nicht ohne Begrenzung bis zur gesamten Speicherkapazität des Servers gespeichert werden. Eine Core-Datei kann Passwörter, Anfrageinhalte und Geschäftsdaten enthalten. Erfassungsumfang, Speichergrenzen und Zugriffsrechte müssen deshalb gemeinsam konfiguriert werden.
1. Absturzart und vorhandenen Collector prüfen
Rufen Sie nach der Zahlung die Zugangsdaten in der Konsole ab und melden Sie sich per SSH an. Die folgenden Schritte erfordern Administratorrechte. Prüfen Sie vor dem Test das System, den freien Speicherplatz und den Übergabemechanismus für Core-Dumps:
cat /etc/os-release
df -h /var/lib
sysctl kernel.core_pattern
sudo journalctl -b -p warning --no-pager
Beginnt kernel.core_pattern mit einem senkrechten Strich, übergibt der Kernel den Dump an ein Programm im Userspace, statt ihn direkt in das aktuelle Verzeichnis zu schreiben. Möglicherweise ist bereits ein anderer Absturz-Collector eingerichtet. Halten Sie den ursprünglichen Wert und die zugehörigen Pakete fest. Richten Sie nicht zwei konkurrierende Mechanismen ein und gehen Sie dann davon aus, dass beide funktionieren.
Unterscheiden Sie zunächst zwischen einem regulär veranlassten Prozessende, einer Beendigung durch ein Signal und dem Beenden wegen Speichermangels. SIGSEGV und SIGABRT lösen normalerweise einen Core-Dump aus, SIGKILL dagegen nicht. Ein Dienststatus, der eine ungewöhnliche Beendigung meldet, bedeutet noch nicht, dass eine abrufbare Datei erzeugt wurde.
Ein Core-Dump enthält Beweismaterial aus dem Prozessspeicher und ist kein gewöhnliches Laufzeitprotokoll. Er darf nicht in einem öffentlichen Verzeichnis liegen und sollte nicht ungeprüft an ein Support-Ticket angehängt oder in ein Code-Repository aufgenommen werden.
Installieren Sie die in dieser Anleitung verwendeten Werkzeuge. Falls die Paketverwaltung den Austausch eines vorhandenen Collectors ankündigt, prüfen Sie zuerst die Auswirkungen und entscheiden Sie sich dann ausdrücklich für einen Mechanismus:
sudo apt-get update
sudo apt-get install systemd-coredump gdb gcc
sysctl kernel.core_pattern
systemctl status systemd-coredump.socket --no-pager
Nach der Installation sollte der Übergabemechanismus auf den Dump-Handler von systemd verweisen. Der Socket nimmt die Daten entgegen; der Verarbeitungsdienst startet bei Bedarf. Dass kein Collector-Prozess dauerhaft läuft, bedeutet daher nicht, dass die Erfassung nicht funktioniert.
2. Speichergrenzen für die Erfassungskette festlegen
Erstellen Sie /etc/systemd/coredump.conf.d/60-controlled-capture.conf mit folgender Konfiguration:
[Coredump]
Storage=external
Compress=yes
ProcessSizeMax=256M
ExternalSizeMax=256M
MaxUse=512M
KeepFree=2G
Diese Kontingente dienen der Funktionsprüfung mit einem kleinen Testprozess. Sie sind keine empfohlenen Werte für speicherintensive Anwendungen. ProcessSizeMax begrenzt die Größe der zur Verarbeitung zugelassenen Dumps, ExternalSizeMax die Größe der extern gespeicherten Dumps. Werden die Grenzen überschritten, bleiben möglicherweise nur die Ereignismetadaten erhalten, aber keine vollständige Speicherdatei.
MaxUse und KeepFree steuern die Belegung des Verzeichnisses für externe Dumps. Sie garantieren weder eine Speicherplatzreserve noch begrenzen sie die Größe der Journal-Datenbank. Gleichzeitige Abstürze können weiterhin zu Speicherplatzengpässen führen. Beobachten Sie deshalb auch den freien Platz auf dem betreffenden Dateisystem.
Die Konfiguration wird von den nachfolgenden Verarbeitungsprozessen eingelesen. Mit diesem Befehl prüfen Sie die zusammengeführte Konfiguration:
systemd-analyze cat-config systemd/coredump.conf
Messen Sie vor dem Einsatz in Produktion den Speicherbedarf eines repräsentativen Prozesses und die tatsächliche Größe seines Dumps. Passen Sie anschließend die Obergrenzen an. Ein erfolgreicher Test mit dem kleinen Programm beweist nicht, dass sich auch der Dump einer speicherintensiven Datenbank vollständig speichern lässt.
3. Einen echten Absturz mit einem isolierten Dienst prüfen
Ein Testprogramm ohne Geschäftsdaten erstellen
Schreiben Sie dieses Minimalprogramm in /tmp/crash-lab.c:
#include <stdlib.h>
int main(void)
{
abort();
}
Legen Sie ein eigenes Systemkonto an und kompilieren Sie das Programm. -g erhält die Debug-Informationen, -O0 erleichtert die Untersuchung des Aufruf-Stacks im Test:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin crashlab
sudo install -d -m 0755 /usr/local/libexec
sudo gcc -g -O0 -o /usr/local/libexec/crash-lab /tmp/crash-lab.c
Existiert das Konto bereits, prüfen Sie zuerst dessen Zweck, statt es erneut anzulegen. Erstellen Sie anschließend /etc/systemd/system/crash-lab.service:
[Unit]
Description=Isolated core dump capture test
[Service]
Type=oneshot
User=crashlab
ExecStart=/usr/local/libexec/crash-lab
LimitCORE=infinity
Restart=no
infinity hebt hier nur die Prozessgrenze für den Testdienst auf. Für den Collector gelten weiterhin die Kontingente aus dem vorherigen Abschnitt. Verwenden Sie diesen Wert nicht als globale Voreinstellung für alle Dienste.
sudo systemctl daemon-reload
sudo systemctl start crash-lab.service
sudo systemctl status crash-lab.service --no-pager
sudo coredumpctl --no-pager list /usr/local/libexec/crash-lab
Eine Fehlermeldung beim Startbefehl ist das erwartete Ergebnis. Es sollte ein Absturzdatensatz erscheinen, der zur ausführbaren Testdatei passt. Falls nicht, prüfen Sie nacheinander den Übergabemechanismus, die Dienstlimits, die Collector-Protokolle und den freien Speicherplatz. Senden Sie zur Prüfung kein Absturzsignal an einen produktiven Prozess.
4. Dump-Datei und Debug-Unterlagen validieren
Notieren Sie aus der Liste die PID dieses Testlaufs. Geben Sie sie innerhalb derselben Administrator-Shell ein und exportieren Sie den Dump in ein eigenes, nicht öffentlich zugängliches Verzeichnis:
sudo -i
read -r -p 'Crash PID: ' CRASH_PID
umask 077
install -d -m 0700 /root/crash-evidence
coredumpctl info "$CRASH_PID"
coredumpctl dump "$CRASH_PID" --output=/root/crash-evidence/test.core
gdb -q -batch \
-ex 'set pagination off' \
-ex 'thread apply all bt' \
/usr/local/libexec/crash-lab /root/crash-evidence/test.core
exit
Prüfen Sie zuerst Ereigniszeit, ausführbare Datei, Signal und Speicherstatus, damit Sie bei einer wiederverwendeten PID nicht den falschen Datensatz abrufen. Das Prüfergebnis sollte SIGABRT zeigen; der Aufruf-Stack muss sich der Funktion main des Testprogramms zuordnen lassen. Fehlender Quellcode für Stack-Frames aus Systembibliotheken verhindert die Validierung der Testkette nicht.
Sind nur Metadaten vorhanden, lässt sich die Datei nicht exportieren oder erscheint ein Hinweis auf einen abgeschnittenen Dump, gilt die vollständige Erfassung nicht als erfolgreich. Auch ein von coredumpctl aufgelistetes Ereignis garantiert nicht, dass die externe Datei noch vorhanden ist.
Für eine reale Anwendung müssen zusätzlich die zum Absturzzeitpunkt verwendete ausführbare Datei, die gemeinsam genutzten Bibliotheken und die passenden Debug-Symbole archiviert werden. Eine aktualisierte Binärdatei mit demselben Namen ist nicht der ursprüngliche Build. Mit readelf -n lässt sich die Build ID prüfen; halten Sie außerdem Paketversionen und Build-Kennungen fest.
Verwenden Sie nicht direkt bt full, da dieser Befehl lokale Variablen ausgibt. Prüfen Sie zunächst den einfachen Aufruf-Stack. Müssen Variablen tatsächlich untersucht werden, arbeiten Sie in einer zugriffsbeschränkten Umgebung und kontrollieren Sie den exportierten Text im Einzelnen. Bewahren Sie auch die Hashwerte kopierter Binärdateien auf, damit ein Austausch der Unterlagen während der Analyse nicht unbemerkt bleibt.
5. Produktionseinbindung und Rücknahme prüfen
Wenn Sie die Erfassung für einen Anwendungsdienst aktivieren, setzen Sie LimitCORE in einem eigenen Drop-in dieses Dienstes. Führen Sie daemon-reload aus und starten Sie den Dienst anschließend im Rahmen einer kontrollierten Änderung neu. Bereits laufende Prozesse erhalten durch eine geänderte Konfigurationsdatei nicht automatisch neue Limits. Prüfen Sie daher die tatsächlichen Prozesslimits unter /proc/PID/limits.
Die Prüfung der Einbindung muss mindestens vier Punkte umfassen:
- Führen automatische Neustarts zu fortlaufenden Dumps, und bleibt die Verzeichnisbelegung unter Kontrolle?
- Erlauben die Kontingente eine vollständige Dump-Datei für einen repräsentativen Anwendungsprozess?
- Liefert das Build-Archiv die passenden Binärdateien, Bibliotheken und Debug-Symbole?
- Ist das Exportverzeichnis nur für berechtigte Personen zugänglich, und enthalten die Unterlagen sensible Daten?
Löschen Sie nach dem Test die Testdienstdatei, das Programm und den Quellcode. Führen Sie anschließend daemon-reload und reset-failed aus. Behandeln Sie die Test-Dumps einzeln anhand des tatsächlichen Pfads aus coredumpctl info. Leeren Sie nicht das gesamte Dump-Verzeichnis mit Platzhaltern.
Um die Erfassungsrichtlinie zurückzunehmen, entfernen Sie die in dieser Anleitung hinzugefügte Konfigurationsdatei. Soll der ursprüngliche Collector wiederhergestellt werden, nutzen Sie dafür die Paketkonfiguration und prüfen Sie danach erneut kernel.core_pattern. Setzen Sie den Übergabewert nicht aus dem Gedächtnis zusammen. Dokumentieren Sie abschließend eine vollständige Abnahme: Das Absturzereignis ist abfragbar, die Datei lässt sich exportieren, der Aufruf-Stack gehört zum richtigen Build und der Zugriff auf die Unterlagen ist beschränkt. So bleibt überprüfbares Material zur Fehlerdiagnose zurück statt einer lediglich eingeschalteten, nie verifizierten Funktion.
Häufig gestellte Fragen
Entsteht bei jedem unerwarteten Prozessende ein Core-Dump?
Nein. Ein bewusstes Beenden oder SIGKILL erzeugt normalerweise keinen Dump. Auch bei geeigneten Signalen können Prozesslimits, Erfassungsregeln oder fehlender Speicher die Aufzeichnung verhindern.
Ist ein in GDB lesbarer Dump bereits ausreichend?
Nein. Binärdatei, Bibliotheken und Debug-Symbole müssen zum abgestürzten Build passen. Außerdem darf der Dump nicht abgeschnitten sein, damit der Stack belastbar ausgewertet werden kann.
Dedizierter Server mit EPYC 7543Pab $450.2/Monat