Normalerweise führe ich ein Programm aus als:
./a.out arg1 arg2 <file
Ich möchte es mit gdb debuggen.
Ich bin mir der set args
Funktionalität bewusst , aber das funktioniert nur über die GDB-Eingabeaufforderung.
Normalerweise führe ich ein Programm aus als:
./a.out arg1 arg2 <file
Ich möchte es mit gdb debuggen.
Ich bin mir der set args
Funktionalität bewusst , aber das funktioniert nur über die GDB-Eingabeaufforderung.
Antworten:
Übergeben Sie die Argumente run
aus gdb an den Befehl.
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
$ gdb ./a.out
dann versucht, (gdb) r < t arg1 arg2
was für mich gut funktioniert. In meinem Fall a.out = nft
arg1 = import
arg2 = json
undt = file containing json rules
Du kannst das:
gdb --args path/to/executable -every -arg you can=think < of
Das magische Stückchen --args
.
run
Geben Sie einfach die gdb-Befehlskonsole ein, um das Debuggen zu starten.
--args
haben, werden keine Argumente an die ausführbare Datei übergeben, daher ist dies kaum mehrdeutig.
argv[0]
der Name der ausführbaren Datei lautet
gdb
selbst in die of
Datei umleiten und dazu führen, dass
Wenn Sie einen bloßen run
Befehl gdb
benötigen, um Ihr Programm mit Umleitungen und Argumenten auszuführen, können Sie Folgendes verwenden set args
:
% gdb ./a.out
(gdb) set args arg1 arg2 <file
(gdb) run
Ich war nicht in der Lage, das gleiche Verhalten mit --args
Parametern zu erreichen , gdb
entgeht den Umleitungen heftig, dh
% gdb --args echo 1 2 "<file"
(gdb) show args
Argument list to give program being debugged when it is started is "1 2 \<file".
(gdb) run
...
1 2 <file
...
Dieser leitet tatsächlich die Eingabe von gdb selbst um, nicht das, was wir hier wirklich wollen
% gdb --args echo 1 2 <file
zsh: no such file or directory: file
Starten Sie GDB für Ihr Projekt.
Wechseln Sie in das Projektverzeichnis, in dem Sie die ausführbare Projektdatei bereits kompiliert haben. Geben Sie den Befehl gdb und den Namen der ausführbaren Datei wie folgt ein:
gdb projectExecutablename
Dies startet gdb und druckt Folgendes: GNU gdb (Ubuntu 7.11.1-0ubuntu1 ~ 16.04) 7.11.1 Copyright (C) 2016 Freie Software Foundation, Inc. ............... .................................. Geben Sie "apropos word" ein, um nach Befehlen zu suchen, die sich auf "word" beziehen. Lesen von Symbolen aus projectExecutablename ... erledigt. (gdb)
Bevor Sie Ihr Programm starten, möchten Sie Ihre Haltepunkte einrichten. Mit dem Befehl break können Sie dies tun. So setzen Sie einen Haltepunkt am Anfang der Funktion main:
(gdb) b main
Sobald Sie die Eingabeaufforderung (gdb) haben, startet der Befehl run die Ausführung der ausführbaren Datei. Wenn für das Programm, das Sie debuggen, Befehlszeilenargumente erforderlich sind, geben Sie diese im Befehl run an. Wenn Sie mein Programm für die Datei "xfiles" ausführen möchten (die sich in einem Ordner "mulder" im Projektverzeichnis befindet), gehen Sie wie folgt vor:
(gdb) r mulder / xfiles
Hoffe das hilft.
Haftungsausschluss: Diese Lösung gehört nicht mir, sondern wurde von https://web.stanford.edu/class/cs107/guide_gdb.html angepasst. Diese kurze Anleitung zu gdb wurde höchstwahrscheinlich an der Stanford University entwickelt.
Wäre es nicht schön, einfach debug
vor einem Befehl zu tippen , um ihn debuggen zu können?gdb
auf Shell-Ebene ?
Darunter diese Funktion. Es funktioniert sogar mit folgenden:
"$program" "$@" < <(in) 1> >(out) 2> >(two) 3> >(three)
Dies ist ein Aufruf, bei dem Sie nichts steuern können, alles variabel ist, Leerzeichen, Zeilenvorschübe und Shell-Metazeichen enthalten kann. In diesem Beispiel in
, out
, two
und three
beliebige andere Befehle , die konsumieren oder produzieren Daten , die müssen nicht geschadet.
Die folgende bash
Funktion wird gdb
in einer solchen Umgebung nahezu sauber aufgerufen [ Gist ]:
debug()
{
1000<&0 1001>&1 1002>&2 \
0</dev/tty 1>/dev/tty 2>&0 \
/usr/bin/gdb -q -nx -nw \
-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\"" exec' \
-ex r \
--args "$@";
}
Beispiel für die Anwendung: Geben Sie einfach debug
vor:
Vor:
p=($'\n' $'I\'am\'evil' " yay ")
"b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
Nach dem:
p=($'\n' $'I\'am\'evil' " yay ")
debug "b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
Das ist es. Jetzt ist es ein Kinderspiel, mit zu debuggen gdb
. Bis auf ein paar Details oder mehr:
gdb
wird nicht automatisch beendet und hält daher die E / A-Umleitung offen, bis Sie beenden gdb
. Aber ich nenne das eine Funktion.
Sie können nicht einfach argv0
wie mit an das Programm übergeben exec -a arg0 command args
. Folgendes sollte diesen Trick tun: Nach dem exec-wrapper
Wechsel "exec
zu "exec -a \"\${DEBUG_ARG0:-\$1}\"
.
Es sind FDs über 1000 offen, die normalerweise geschlossen sind. Wenn dies ein Problem ist, wechseln Sie 0<&1000 1>&1001 2>&1002
zu Lesen0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-
Sie können nicht zwei Debugger gleichzeitig ausführen. Es kann auch Probleme geben, wenn ein anderer Befehl /dev/tty
(oder STDIN) verwendet wird. Um dies zu beheben, ersetzen Sie /dev/tty
durch "${DEBUGTTY:-/dev/tty}"
. In einem anderen TTY-Typ tty; sleep inf
und verwenden Sie dann das gedruckte TTY (i. E. /dev/pts/60
) zum Debuggen, wie in DEBUGTTY=/dev/pts/60 debug command arg..
. Das ist die Kraft von Shell, gewöhne dich daran!
Funktion erklärt:
1000<&0 1001>&1 1002>&2
bewegt die ersten 3 FDs weg
0</dev/tty 1>/dev/tty 2>&0
stellt die ersten 3 FDs wieder her, die auf Ihre aktuelle TTY verweisen. So können Sie steuern gdb
./usr/bin/gdb -q -nx -nw
Läuft gdb
Aufrufe gdb
auf Shell-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\""
Erstellt einen Start-Wrapper, der die ersten 3 FDs wiederherstellt, die auf 1000 und höher gespeichert wurden-ex r
startet das Programm mit dem exec-wrapper
--args "$@"
Übergibt die Argumente wie angegebenWar das nicht einfach?
r
ist die Abkürzung fürrun
und Sie können ihm mit beliebigen Argumenten folgen. Wie in dieser Frage wäre es:r arg1 arg2 <file
oder es könnte seinrun arg1 arg2 <file