Come passare argomenti e reindirizzare lo stdin da un file al programma eseguito in gdb?


Risposte:


136

Passa gli argomenti al runcomando dall'interno di gdb.

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

3
rè l'abbreviazione di rune puoi seguirlo con qualsiasi argomento. Come in questa domanda, sarebbe: r arg1 arg2 <fileo potrebbe essererun arg1 arg2 <file
phyatt il

Per me non funziona. Poi ho provato $ gdb ./a.outallora (gdb) r < t arg1 arg2che funziona bene per me. Nel mio caso a.out = nft arg1 = import arg2 = json et = file containing json rules
mystictot il

410

Puoi farlo:

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

L'essere magico --args.

Basta digitare runnella console di comando gdb per avviare il debug.


24
All'inizio pensavo di aver letto male; strano che --args preceda l'eseguibile. Ma così è!
Caolin Fire,

8
@Kaolin --args deve precedere l'eseguibile perché è un interruttore per gdb. Se venisse dopo, come lo distinguerebbe gdb da un argomento che vorresti passare all'eseguibile che stai eseguendo il debug?
codehippo,

9
@codehippo: Beh, se non lo hai specificato, non --argsci sono argomenti passati all'eseguibile, quindi non è certo ambiguo.
Corse della leggerezza in orbita

14
Immagino sia perché convenzionalmente argv[0]è il nome dell'eseguibile
Claudiu

3
questo reindirizzerà l'input di gdbse stesso nel offile e provocherà gdb che tenta di eseguire comandi da esso
unkulunkulu,

4

Se si desidera avere il runcomando nudo gdbper 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 --argsparametro, gdbsfugge 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

1

Avvia GDB sul tuo progetto.

  1. 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)

  1. 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

  2. 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.


0

Non sarebbe bello semplicemente digitare debugdavanti a qualsiasi comando per poterlo eseguire il debug a gdblivello 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 threesono arbitrarie altri comandi che consumano o dati producono che non devono essere danneggiati.

La seguente bashfunzione richiama in gdbmodo 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 debugdavanti:

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ù:

  • gdbnon si chiude automaticamente e quindi mantiene aperto il reindirizzamento IO fino all'uscita gdb. Ma io lo chiamo una caratteristica.

  • Non puoi passare facilmente argv0al programma come con exec -a arg0 command args. Di seguito dovrebbe fare questo trucco: dopo il exec-wrapperpassaggio "execa "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>&1002passa 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/ttycon "${DEBUGTTY:-/dev/tty}". In qualche altro tipo TTY tty; sleep infe 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
    • Ciò presuppone che gli FD 1000, 1001 e 1002 siano gratuiti
  • 0</dev/tty 1>/dev/tty 2>&0ripristina i primi 3 FD per puntare all'attuale TTY. Quindi puoi controllare gdb.
  • /usr/bin/gdb -q -nx -nwesegue gdbinvoca gdbsu 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 indicato

Non è stato facile?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.