2009-09-21 22 views
35

Digamos que tengo dos programas llamados blah y ret. Quiero depurar el programa bla que recibe la entrada del programa ret a través de la redirección de E/S. ¿Cómo puedo depurar el programa blah en el siguiente caso usando gdb?gdb - depuración con tubería

bash> ret | blah 
+0

¿Es esto diferente a: http://stackoverflow.com/questions/4521015/how-to-pass-arguments-and-redirect-stdin-from-a-file-to-program-run-in-gdb –

Respuesta

41

Al principio, puede ejecutar el programa y depurarlo pid. Esta solución, por supuesto, no cubre todos los casos.

Otro enfoque es utilizar las capacidades de Linux para la comunicación entre procesos. En resumen, redirige la salida de ret a un archivo especial FIFO ("named pipe") y luego lee de esa FIFO a través de un depurador. Así es como se hace. De golpe, ejecute:

mkfifo foo 

Esto crea un archivo especial en el directorio que servirá como un tubo llamado . Cuando escribe texto en este archivo (usando la misma sintaxis echo "Hello" >foo), el programa de escritura se bloqueará hasta que alguien lea los datos del archivo (cat <foo, por ejemplo). En nuestro caso, un proceso controlado por gdb leerá desde este archivo.

Después de crear un FIFO, van desde bash:

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

A continuación, en el símbolo del BGF, ejecute

run <foo 

y obtener el efecto deseado. Tenga en cuenta que no puede leer los datos de fifo (ni tampoco de un conducto habitual) dos veces: cuando haya leído todos los datos, el proceso blah fallece y debe repetir el comando escribiendo a foo (puede hacerlo) desde la otra ventana de shell).

Cuando haya terminado, elimine el fifo con rm foo (o colóquelo en el directorio donde se eliminará automáticamente al reiniciar el sistema, como /tmp).

+1

Si puede pagar el espacio en disco, también puede simplemente conectarlo a un archivo 'foo', en lugar de un FIFO 'foo' (le ahorra un comando :). – Frank

+7

Los archivos regulares y los FIFO/pipes tienen una semántica diferente para read(). Si llega a EOF en un archivo normal, read() regresa con tal vez menos bytes de lectura que los especificados. Si lee desde un FIFO/tubería, lea() bloques hasta que llegue el número especificado de bytes o haya salido el proceso de escritura en el conducto. – SzG

9

El comando run de GDB usa bash para realizar la redirección. Una forma simple de lograr el equivalente de ret | blah es usar la función process substitution de bash.

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

Explicación: Bash sustituye <(ret) con algo como /dev/fd/123, que es un descriptor de archivo de la salida estándar de ret. Podemos usar ese fd de manera similar a un FIFO con nombre como se describe en la otra respuesta, excepto que no tenemos que crearlo manualmente nosotros mismos, ni preocuparnos por la duración del proceso ret.

+0

Se adapta exactamente a mis necesidades, gracias. – Limeth

+0

Esto no funciona para zsh. ¿Hay una alternativa? – redfast00

+0

La sustitución de procesos funciona igual en zsh que en bash. ¿Cuál es tu invocación y qué mensaje de error encuentras? –

Cuestiones relacionadas