2009-09-21 14 views
35

dire che ho un due programmi denominati bla e ret. Voglio eseguire il debug del programma blah che riceve input dal programma ret tramite reindirizzamento I/O. Come faccio a eseguire il debug del programma blah nel seguente caso utilizzando gdb?gdb - il debugging con tubo

bash> ret | blah 
+0

È diverso da: http://stackoverflow.com/questions/4521015/how-to-pass-arguments-and-redirect-stdin-from-a-file-to-program-run-in-gdb –

risposta

41

In un primo momento, si può eseguire il programma ed eseguire il debug da pid. Questa soluzione, ovviamente, non copre tutti i casi.

Un altro approccio è utilizzare le funzionalità di Linux per la comunicazione tra processi. In breve, si reindirizza l'output di ret in un file speciale FIFO ("named pipe") e quindi si legge dalla FIFO tramite il debugger. Ecco come è fatto. Da bash, eseguire:

mkfifo foo 

Questo crea un file speciale nella directory che servirà come una pipa denominata . Quando scrivi del testo su questo file (usando la stessa sintassi echo "Hello" >foo), il programma di scrittura bloccherà fino a quando qualcuno non leggerà i dati dal file (cat <foo, per esempio). Nel nostro caso, un file controllato da gdb leggerà da questo file.

Dopo aver creato una FIFO, eseguito da bash:

ret > foo & # ampersand because it may block as nobody is reading from foo 
gdb blah 

Poi, nel prompt di gdb, eseguire

run <foo 

E ottenere l'effetto desiderato. Nota che non puoi leggere i dati dal fifo (come da una solita pipe) due volte: quando hai letto tutti i dati, il processo blah muore e dovresti ripetere il comando scrivendo a foo (puoi farlo dall'altra finestra della shell).

Al termine, rimuovere il fifo con rm foo (o inserirlo nella directory in cui verrà automaticamente rimosso al riavvio del sistema, ad esempio /tmp).

+1

Se puoi permetterti lo spazio su disco, puoi anche inserirlo in un normale file 'pippo', invece di un FIFO' pippo' (ti salva un comando :). – Frank

+7

I file regolari e FIFO/pipe hanno semantica diversa per read(). Se si raggiunge EOF in un file normale, read() restituisce probabilmente meno byte letti di quelli specificati. Se leggi da un blocco FIFO/pipe, leggi() fino a quando arriva il numero specificato di byte, o il processo di scrittura nella pipe è terminato. – SzG

9

Il comando GDB run utilizza bash per eseguire il reindirizzamento. Un modo semplice per ottenere l'equivalente di ret | blah consiste nell'utilizzare la funzione process substitution di bash.

$ gdb blah 
... 
(gdb) run < <(ret) 

Spiegazione: bash sostituisce <(ret) con qualcosa come /dev/fd/123, che è un descrittore di file del stdout di ret. Possiamo usarlo in modo simile a un FIFO con nome come descritto nell'altra risposta, tranne per il fatto che non dobbiamo crearlo manualmente da soli, né preoccuparci della durata del processo ret.

+0

Si adatta perfettamente alle mie esigenze, grazie. – Limeth

+0

Questo non funziona per zsh. C'è un'alternativa? – redfast00

+0

La sostituzione del processo funziona allo stesso modo in zsh come in bash. Qual è la tua invocazione e quale messaggio di errore riscontri? –