Mein Programm funktioniert folgendermaßen:
exe -p param1 -i param2 -o param3
Es stürzte ab und erzeugte eine Core-Dump-Datei. core.pid
.
Ich möchte die Core-Dump-Datei von analysieren
gdb ./exe -p param1 -i param2 -o param3 core.pid
GDB erkennt jedoch die Parameter der EXE-Datei als Eingabe von GDB.
Wie analysiere ich in dieser Situation eine Core-Dump-Datei?
exe
es sich nicht um ein Shell-Skript handelt (um einige Variablen usw. festzulegen), wie z. B.firefox
unter Linux?Antworten:
Sie können den Kern mit GDB auf viele Arten verwenden, aber die Übergabe von Parametern, die an die ausführbare Datei an GDB übergeben werden sollen, ist nicht die Möglichkeit, die Kerndatei zu verwenden. Dies könnte auch der Grund sein, warum Sie diesen Fehler erhalten haben. Sie können die Kerndatei folgendermaßen verwenden:
gdb <executable> <core-file>
odergdb <executable> -c <core-file>
oderBei Verwendung der Kerndatei müssen Sie keine Argumente übergeben. Das Absturzszenario wird in GDB angezeigt (überprüft mit GDB Version 7.1 unter Ubuntu).
Beispielsweise:
Wenn Sie Parameter an die ausführbare Datei übergeben möchten, die in GDB debuggt werden soll, verwenden Sie
--args
.Beispielsweise:
Manpages sind hilfreich, um andere GDB-Optionen anzuzeigen.
quelle
Einfache Verwendung von GDB zum Debuggen von Coredump-Dateien:
Eine Coredump-Datei für einen "Prozess" wird als "core.pid" -Datei erstellt.
Geben Sie Folgendes ein, nachdem Sie die GDB-Eingabeaufforderung aufgerufen haben (bei Ausführung des obigen Befehls):
Dadurch erhalten Sie die Informationen des Stapels, in denen Sie die Ursache des Absturzes / Fehlers analysieren können. Ein anderer Befehl für die gleichen Zwecke lautet:
Dies ist das gleiche wie oben. Konventionell werden die gesamten Stapelinformationen aufgelistet (was letztendlich zum Absturzort führt).
quelle
Überspringen Sie einfach die Parameter. GDB braucht sie nicht:
quelle
objdump
+gdb
minimales lauffähiges BeispielTL; DR:
objdump -s core
kann verwendet werden, um Speicher in großen Mengen zu sichernNun zum vollständigen Testaufbau:
Haupt c
Kompilieren und ausführen, um den Kern zu generieren:
Ausgabe:
GDB verweist uns auf die genaue Zeile, in der der Segmentierungsfehler aufgetreten ist. Dies möchten die meisten Benutzer beim Debuggen:
dann:
Das zeigt uns direkt auf die Buggy-Linie 7.
CLI-Argumente werden in der Kerndatei gespeichert und müssen nicht erneut übergeben werden
Um die spezifischen CLI-Argumentfragen zu beantworten, sehen wir, dass, wenn wir die cli-Argumente ändern, z. B.:
dann spiegelt sich dies in der vorherigen Bactrace wider, ohne dass Änderungen an unseren Befehlen vorgenommen wurden:
Also beachte wie jetzt
argc=3
. Daher muss dies bedeuten, dass die Kerndatei diese Informationen speichert. Ich vermute, es speichert es nur als Argumente vonmain
, genauso wie es die Argumente anderer Funktionen speichert.Dies ist sinnvoll, wenn Sie bedenken, dass der Core-Dump den gesamten Speicher- und Registerstatus des Programms speichern muss und daher alle Informationen enthält, die zum Bestimmen des Werts von Funktionsargumenten auf dem aktuellen Stapel erforderlich sind.
Weniger offensichtlich ist, wie die Umgebungsvariablen überprüft werden: So erhalten Sie Umgebungsvariablen aus einem Core-Dump Umgebungsvariablen sind auch im Speicher vorhanden, sodass der objdump diese Informationen enthält, aber ich bin nicht sicher, wie ich sie alle auf einmal bequem auflisten kann , eins nach dem anderen wie folgt hat an meinen Tests gearbeitet:
Binutils-Analyse
Durch die Verwendung von binutils-Tools wie
readelf
undobjdump
können wir die in dercore
Datei wie den Speicherstatus erstellen.Das meiste / alles muss auch über GDB sichtbar sein, aber diese binutils-Tools bieten einen umfangreicheren Ansatz, der für bestimmte Anwendungsfälle praktisch ist, während GDB für eine interaktivere Erkundung bequemer ist.
Zuerst:
sagt uns, dass die
core
Datei tatsächlich eine ELF- Datei ist:Deshalb können wir es mit den üblichen binutils-Werkzeugen direkter untersuchen.
Ein kurzer Blick auf den ELF-Standard zeigt, dass es tatsächlich einen ELF-Typ gibt, der diesem gewidmet ist:
Weitere Formatinformationen finden Sie unter:
Dann:
gibt einige Hinweise zur Dateistruktur. Der Speicher scheint in regulären Programm-Headern enthalten zu sein:
In einem Notizbereich sind weitere Metadaten vorhanden, insbesondere
prstatus
der PC :objdump
kann leicht den gesamten Speicher entleeren mit:was beinhaltet:
Das stimmt genau mit dem Standardwert in unserem Lauf überein.
Dies wurde unter Ubuntu 16.04 amd64, GCC 6.4.0 und binutils 2.26.1 getestet.
quelle
Aus dem GDB-Debugger-Tutorial von RMS :
Stellen Sie sicher, dass Ihre Datei wirklich ein
core
Bild ist - überprüfen Sie sie mitfile
.quelle
Mit einem etwas anderen Ansatz können Sie GDB vollständig überspringen. Wenn Sie nur eine Rückverfolgung wünschen, fängt das Linux-spezifische Dienstprogramm 'catchsegv' SIGSEGV ab und zeigt eine Rückverfolgung an.
quelle
Es spielt keine Rolle, ob die ausführbare Datei Argumente enthält oder nicht. Um GDB auf einer beliebigen Binärdatei mit einer generierten Kerndatei auszuführen, finden Sie unten die Syntax.
Lassen Sie mich das folgende Beispiel zum besseren Verständnis nehmen.
Anhand der obigen Ausgabe können Sie etwas über den Kern erraten, ob es sich um einen NULL-Zugriff, SIGABORT usw. handelt.
Diese Zahlen Nr. 0 bis Nr. 10 sind die Stapelrahmen von GDB. Diese Stapelrahmen gehören nicht zu Ihrer Binärdatei. Wenn Sie in den obigen 0 - 10 Frames den Verdacht haben, dass etwas nicht stimmt, wählen Sie diesen Frame aus
Nun, um mehr Details darüber zu sehen:
Um das Problem weiter zu untersuchen, können Sie hier zu diesem Zeitpunkt die vermuteten Variablenwerte drucken.
quelle
Geben Sie einfach den Befehl ein:
Oder
Es ist nicht erforderlich, ein Befehlszeilenargument anzugeben. Der Code-Dump, der aufgrund einer früheren Übung generiert wurde.
quelle
Sie können die Core-Dump-Datei mit dem Befehl "gdb" analysieren.
quelle