it-swarm.com.de

Wie kann man Argumente übergeben und stdin aus einer Datei in gdb ausführen

Ich führe normalerweise ein Programm aus als:

./a.out arg1 arg2 <file

Ich möchte es mit gdb debuggen.

Ich kenne die set args-Funktionalität, aber das funktioniert nur von der gdb-Eingabeaufforderung.

206
user277465

Übergeben Sie die Argumente innerhalb von gdb an den Befehl run.

$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
133
marcog

Du kannst das:

gdb --args path/to/executable -every -arg you can=think < of

Das magische Bit ist --args.

Geben Sie einfach run in die gdb-Befehlskonsole ein, um das Debuggen zu starten.

406
rubenvb

Wenn Sie den Befehl run in gdb haben möchten, um Ihr Programm mit Umleitungen und Argumenten auszuführen, können Sie set args verwenden:

% gdb ./a.out
(gdb) set args arg1 arg2 <file
(gdb) run

Mit --args-Parameter konnte ich nicht dasselbe Verhalten erzielen, gdb entgeht den Weiterleitungen heftig, d. H.

% 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 die Eingabe von gdb selbst um, nicht was wir hier wirklich wollen

% gdb --args echo 1 2 <file
zsh: no such file or directory: file
3
unkulunkulu

Starten Sie GDB für Ihr Projekt. 

  1. Wechseln Sie in das Projektverzeichnis, in dem Sie die Projektdatei bereits kompiliert haben. Geben Sie den Befehl gdb und den Namen der ausführbaren Datei wie folgt aus:

    gdb projectExecutablename

Dies startet gdb und druckt Folgendes aus: GNU gdb (Ubuntu 7.11.1-0ubuntu1 ~ 16.04) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc ....... ............................................ Geben Sie "apropos Word" ein "um nach Befehlen zu suchen, die mit" Word "zu tun haben ... Lesen von Symbolen aus projectExecutablename ... done . (gdb)

  1. Bevor Sie Ihr Programm starten, möchten Sie Ihre Haltepunkte einrichten. Mit dem Befehl break können Sie dies tun. So legen Sie einen Haltepunkt am Anfang der Funktion namens main fest:

    (gdb) b main

  2. Sobald Sie die Eingabeaufforderung (gdb) haben, startet der Befehl run die Ausführung der ausführbaren Datei. Wenn das Programm, das Sie debuggen, Befehlszeilenargumente erfordert, geben Sie sie dem Ausführungsbefehl an. Wenn Sie mein Programm in der Datei "xfiles" ausführen möchten (die sich in einem Ordner "mulder" im Projektverzeichnis befindet), führen Sie folgende Schritte aus:

    (gdb) r mulder/xfiles

Hoffe das hilft. 

Haftungsausschluss: Diese Lösung ist nicht von mir, sie 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 .

1
Ehsan

Wäre es nicht schön, einfach debug vor einem Befehl einzugeben, um ihn mit gdb auf Shell-Ebene debuggen zu können?

Darunter diese Funktion. Es funktioniert sogar mit folgendem:

"$program" "[email protected]" < <(in) 1> >(out) 2> >(two) 3> >(three)

Dies ist ein Aufruf, bei dem Sie nichts steuern können, alles ist variabel und kann Leerzeichen, Zeilenvorschübe und Shell-Metazeichen enthalten. In diesem Beispiel sind in, out, two und three beliebige andere Befehle, die Daten verbrauchen oder erzeugen, die nicht beschädigt werden dürfen.

Die folgende bash-Funktion ruft gdb in einer solchen Umgebung nahezu sauber auf [ 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 \"\[email protected]\"" exec' \
  -ex r \
  --args "[email protected]";
}

Beispiel, wie Sie dies anwenden: 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 absolutes Kinderspiel, mit gdb zu debuggen. Bis auf ein paar Details oder mehr:

  • gdb wird nicht automatisch beendet und hält daher die IO -Umleitung offen, bis Sie gdb beenden. Aber ich nenne das eine Funktion.

  • Sie können argv0 nicht wie exec -a arg0 command args an das Programm übergeben. Folgendes sollte diesen Trick ausführen: Ändern Sie nach exec-wrapper"exec in "exec -a \"\${DEBUG_ARG0:-\$1}\".

  • Über 1000 offene FDs sind normalerweise geschlossen. Wenn dies ein Problem ist, ändern Sie 0<&1000 1>&1001 2>&1002 in 0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-.

  • Sie können nicht zwei Debugger parallel ausführen. Es können auch Probleme auftreten, wenn ein anderer Befehl /dev/tty (oder STDIN) verwendet. Um dies zu beheben, ersetzen Sie /dev/tty durch "${DEBUGTTY:-/dev/tty}". Geben Sie in einem anderen TTY tty; sleep inf ein und verwenden Sie dann das gedruckte TTY (d. H. /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 verschiebt die ersten 3 FDs
    • Dies setzt voraus, dass die FDs 1000, 1001 und 1002 frei sind
  • 0</dev/tty 1>/dev/tty 2>&0 stellt die ersten 3 FDs wieder her und zeigt auf Ihren aktuellen TTY. So können Sie gdb steuern.
  • /usr/bin/gdb -q -nx -nw führt gdb aus, um gdb in der Shell aufzurufen
  • -ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\[email protected]\"" 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 "[email protected]" übergibt die Argumente wie angegeben

War das nicht einfach?

0
Tino