Di solito eseguo un programma come:
./a.out arg1 arg2 <file
Vorrei eseguire il debug usando gdb.
Sono a conoscenza della set args
funzionalità, ma funziona solo dal prompt di gdb.
Di solito eseguo un programma come:
./a.out arg1 arg2 <file
Vorrei eseguire il debug usando gdb.
Sono a conoscenza della set args
funzionalità, ma funziona solo dal prompt di gdb.
Risposte:
Passa gli argomenti al run
comando dall'interno di gdb.
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
$ gdb ./a.out
allora (gdb) r < t arg1 arg2
che funziona bene per me. Nel mio caso a.out = nft
arg1 = import
arg2 = json
et = file containing json rules
Puoi farlo:
gdb --args path/to/executable -every -arg you can=think < of
L'essere magico --args
.
Basta digitare run
nella console di comando gdb per avviare il debug.
--args
ci sono argomenti passati all'eseguibile, quindi non è certo ambiguo.
argv[0]
è il nome dell'eseguibile
gdb
se stesso nel of
file e provocherà gdb che tenta di eseguire comandi da esso
Se si desidera avere il run
comando nudo gdb
per eseguire il programma con reindirizzamenti e argomenti, è possibile utilizzare set args
:
% gdb ./a.out
(gdb) set args arg1 arg2 <file
(gdb) run
Non sono stato in grado di ottenere lo stesso comportamento con il --args
parametro, gdb
sfugge fortemente ai reindirizzamenti, vale a dire
% 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
...
Questo in realtà reindirizza l'input di gdb stesso, non quello che vogliamo davvero qui
% gdb --args echo 1 2 <file
zsh: no such file or directory: file
Avvia GDB sul tuo progetto.
Vai alla directory del progetto, dove hai già compilato l'eseguibile del progetto. Immettere il comando gdb e il nome dell'eseguibile come di seguito:
gdb projectExecutablename
Questo avvia gdb, stampa quanto segue: GNU gdb (Ubuntu 7.11.1-0ubuntu1 ~ 16.04) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. ............... .................................. Digita "apropos word" per cercare comandi relativi a "word". Lettura dei simboli dal projectExecutablename ... fatto. (Gdb)
Prima di avviare il programma in esecuzione, si desidera impostare i punti di interruzione. Il comando break ti consente di farlo. Per impostare un punto di interruzione all'inizio della funzione denominata main:
(gdb) b principale
Una volta che hai il prompt (gdb), il comando run avvia l'esecuzione eseguibile. Se il programma di cui si sta eseguendo il debug richiede argomenti della riga di comando, è necessario specificarli nel comando di esecuzione. Se volessi eseguire il mio programma sul file "xfiles" (che si trova in una cartella "mulder" nella directory del progetto), faresti quanto segue:
(gdb) r mulder / xfiles
Spero che questo ti aiuti.
Disclaimer: questa soluzione non è mia, è adattata da https://web.stanford.edu/class/cs107/guide_gdb.html Questa breve guida a gdb è stata, molto probabilmente, sviluppata alla Stanford University.
Non sarebbe bello semplicemente digitare debug
davanti a qualsiasi comando per poterlo eseguire il debug a gdb
livello di shell?
Sotto di essa questa funzione. Funziona anche con i seguenti:
"$program" "$@" < <(in) 1> >(out) 2> >(two) 3> >(three)
Questa è una chiamata in cui non puoi controllare nulla, tutto è variabile, può contenere spazi, avanzamenti di riga e metacaratteri di shell. In questo esempio, in
, out
, two
, e three
sono arbitrarie altri comandi che consumano o dati producono che non devono essere danneggiati.
La seguente bash
funzione richiama in gdb
modo quasi pulito in un tale ambiente [ 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 "$@";
}
Esempio su come applicare questo: basta digitare debug
davanti:
Prima:
p=($'\n' $'I\'am\'evil' " yay ")
"b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
Dopo:
p=($'\n' $'I\'am\'evil' " yay ")
debug "b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
Questo è tutto. Ora è un gioco da ragazzi con cui eseguire il debug gdb
. Tranne qualche dettaglio o più:
gdb
non si chiude automaticamente e quindi mantiene aperto il reindirizzamento IO fino all'uscita gdb
. Ma io lo chiamo una caratteristica.
Non puoi passare facilmente argv0
al programma come con exec -a arg0 command args
. Di seguito dovrebbe fare questo trucco: dopo il exec-wrapper
passaggio "exec
a "exec -a \"\${DEBUG_ARG0:-\$1}\"
.
Ci sono FD superiori a 1000 aperti, che normalmente sono chiusi. Se questo è un problema, 0<&1000 1>&1001 2>&1002
passa a leggere0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-
Non è possibile eseguire due debugger in parallelo. Potrebbero esserci anche problemi se si consuma qualche altro comando /dev/tty
(o STDIN). Per risolvere il problema, sostituirlo /dev/tty
con "${DEBUGTTY:-/dev/tty}"
. In qualche altro tipo TTY tty; sleep inf
e quindi utilizzare il TTY stampato (i. E. /dev/pts/60
) per il debug, come in DEBUGTTY=/dev/pts/60 debug command arg..
. Questo è il potere di Shell, abituati!
Funzione spiegata:
1000<&0 1001>&1 1002>&2
sposta i primi 3 FD
0</dev/tty 1>/dev/tty 2>&0
ripristina i primi 3 FD per puntare all'attuale TTY. Quindi puoi controllare gdb
./usr/bin/gdb -q -nx -nw
esegue gdb
invoca gdb
su shell-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\""
crea un wrapper di avvio, che ripristina i primi 3 FD salvati a 1000 e versioni successive-ex r
avvia il programma usando il exec-wrapper
--args "$@"
passa gli argomenti come indicatoNon è stato facile?
r
è l'abbreviazione dirun
e puoi seguirlo con qualsiasi argomento. Come in questa domanda, sarebbe:r arg1 arg2 <file
o potrebbe essererun arg1 arg2 <file