Ich erhalte jedes Mal einen ärgerlichen Fehler, wenn gdb eine Ausnahme abfängt. Ich habe das folgende Beispielprogramm ausgeführt
#include <stdexcept>
int main() {
throw std::invalid_argument("");
return 0;
}
Und das Ergebnis des Ausführens von gdb ist
terminate called after throwing an instance of 'std::invalid_argument'
what():
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
Es ist nicht so schlimm, da ich die Informationen bekomme, die ich brauche, es nervt mich nur…
Weiß jemand, wie man das beheben kann?
Um ein vollständiges Quellcode-Debugging der C-Bibliothek unter Ubuntu durchzuführen, sind nur wenige Schritte erforderlich:
-
Installieren Sie die Debuginfo-Version von libc6.
Es ist wahrscheinlich bereits installiert – das gdb-Paket auf Ubuntu hat eine Abhängigkeit davon – aber falls nicht, führen Sie es aus sudo apt install libc6-dbg
.
-
Bereiten Sie das Paketsystem darauf vor, Quellcodepakete herunterzuladen und zu verarbeiten, falls dies noch nicht geschehen ist.
sudo apt install dpkg-dev
grep deb-src /etc/apt/sources.list
Die Ausgabe von Grep sollte angezeigt werden (und möglicherweise gibt es zusätzliche Übereinstimmungen, um die wir uns keine Sorgen machen müssen):
deb-src http://archive.ubuntu.com/ubuntu/ bionic main restricted
deb-src http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted
Wenn das grep zeigt, dass diese deb-src
Zeilen werden mit auskommentiert #
:
# deb-src http://archive.ubuntu.com/ubuntu/ bionic main restricted
# deb-src http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted
dann bearbeiten /etc/apt/sources.list
um die zu entfernen #
am Anfang dieser Zeilen und dann laufen sudo apt update
.
-
Laden Sie den Quellcode herunter, der der installierten Version der C-Bibliothek entspricht.
Erstellen Sie zunächst irgendwo ein Verzeichnis – ich werde es verwenden /opt/src
Hier.
Gehen Sie dann wie folgt vor:
cd /opt/src
apt source libc6
Wenn die apt
Befehl gibt eine Fehlermeldung wie
E: Sie müssen einige ‘Quell’-URIs in Ihre sources.list aufnehmen
dann sind meine Anweisungen in Schritt 2 möglicherweise veraltet; poste hier einen Kommentar.
Wenn der Download abgeschlossen ist, führen Sie Folgendes aus:
find $PWD -maxdepth 1 -type d -name 'glibc*'
Merken Sie sich diesen Namen – er wird so etwas wie sein /opt/src/glibc-2.23
-
Bestimmen Sie, wo gdb erwartet, den Quellcode zu finden, und nehmen Sie entsprechende Anpassungen vor.
Führen Sie gdb aus, lassen Sie es Ihr Programm ausführen, bis es stoppt, und tun Sie dies an der gdb-Eingabeaufforderung:
(gdb) info source
Current source file is ../sysdeps/unix/sysv/linux/raise.c
Compilation directory is /build/glibc-KM3i_a/glibc-2.23/signal
gdb erwartet also, dass der Quellcode da ist /build/glibc-KM3i_a/glibc-2.23
. Es gibt zwei Möglichkeiten, dies zu beheben:
- Verschieben (oder verwenden Sie einen Symlink), sodass der Quellcode darin ist (oder zu sein scheint).
/build/glibc-KM3i_a/glibc-2.23
.
oder
-
Teilen Sie gdb mit, wie der richtige Pfadname des Quellverzeichnisses ersetzt werden soll:
(gdb) set substitute-path /build/glibc-KM3i_a/glibc-2.23 /opt/src/glibc-2.23
Gehen Sie nun zurück zu Ihrem Frame und gdb sollte die Quellcodezeile anzeigen:
(gdb) frame 1
#1 0xb7e2fea9 in __GI_raise (sig=6) at ../sysdeps/unix/sysv/linux/raise.c:54
return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
Verwenden Sie den Paketmanager für Ihre Distribution und suchen Sie nach dieser Datei?
– UKMonkey
16. Januar 2018 um 10:21 Uhr
Ich tat. Es ist im gnulib-Paket enthalten, befindet sich aber nach der Installation in /usr/share/gnulib/lib/raise.c. Gdb findet es nicht.
– ClausH
16. Januar 2018 um 10:23 Uhr
Hier gibt es nichts zu reparieren. Auch wenn du holst
raise.c
und sehen können, was in dieser Zeile vor sich geht, wäre es nur Zeitverschwendung, da es nicht Teil Ihres Codes ist, der tatsächlich das Auslösen einer Ausnahme verursacht hat.– Benutzer7860670
16. Januar 2018 um 10:23 Uhr
Ich werde einen anderen Weg gehen. Es ist dir egal. Sie brauchen den Quellcode von raise nicht. Sobald raise() aufgerufen wird, wissen Sie, dass eine Bestätigung fehlgeschlagen ist oder eine Ausnahme ausgelöst wurde. Drucken Sie die Aufrufliste (
bt
) und zum entsprechenden Frame wechseln (frame n
), um Ihren Code zu debuggen.– JSC
16. Januar 2018 um 10:24 Uhr
‘es nervt mich nur’ nein nein nein … es debuggt dich 😉
– UKMonkey
16. Januar 2018 um 10:26 Uhr