c++ archivos - ¿Cómo pasar argumentos y redirigir la entrada estándar de un archivo a un programa ejecutado en gdb?




fopen (5)

Normalmente ejecuto un programa como:

./a.out arg1 arg2 <file

Me gustaría depurarlo usando gdb.

Soy consciente de la funcionalidad de set args del set args , pero eso solo funciona desde el indicador de gdb.


Answers

Pase los argumentos al comando de run desde gdb.

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

Si desea tener el comando " run en gdb para ejecutar su programa con redirecciones y argumentos, puede usar set args :

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

No pude lograr el mismo comportamiento con el parámetro --args , gdb escapa fieramente a las redirecciones, es decir

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

Este realmente redirige la entrada de gdb en sí, no lo que realmente queremos aquí

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

Puedes hacerlo:

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

La broca mágica está --args .

Simplemente escriba run en la consola de comandos gdb para iniciar la depuración.


¿No sería agradable simplemente escribir debug delante de cualquier comando para poder depurarlo con gdb en el nivel de shell?

Debajo de esta función. Incluso funciona con los siguientes:

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

Esta es una llamada en la que no puede controlar nada, todo es variable, puede contener espacios, saltos de línea y metacaracteres de shell. En este ejemplo, in , out , two y three son otros comandos arbitrarios que consumen o producen datos que no deben ser dañados.

La siguiente función de bash invoca gdb casi limpia en dicho entorno [ 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]";
}

Ejemplo sobre cómo aplicar esto: Simplemente escriba debug en frente:

Antes de:

p=($'\n' $'I\'am\'evil' "  yay  ")
"b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)

Después:

p=($'\n' $'I\'am\'evil' "  yay  ")
debug "b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)

Eso es. Ahora es un absoluto obvio para depurar con gdb . Excepto algunos detalles o más:

  • gdb no se cierra automáticamente y, por lo tanto, mantiene abierta la redirección de IO hasta que salga de gdb . Pero llamo a esto una característica.

  • No puede pasar fácilmente argv0 al programa como con el exec -a arg0 command args . Lo siguiente debería hacer este truco: después de que exec-wrapper cambie "exec a "exec -a \"\${DEBUG_ARG0:-\$1}\" .

  • Hay FDs por encima de 1000 abiertos, que normalmente están cerrados. Si esto es un problema, cambie 0<&1000 1>&1001 2>&1002 para leer 0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-

  • No puede ejecutar dos depuradores en paralelo. También puede haber problemas, si algún otro comando consume /dev/tty (o STDIN). Para solucionarlo, reemplace /dev/tty con "${DEBUGTTY:-/dev/tty}" . En algún otro tipo de TTY tty; sleep inf tty; sleep inf y luego use el TTY impreso (i. E. /dev/pts/60 ) para la depuración, como en DEBUGTTY=/dev/pts/60 debug command arg.. Ese es el Poder de Shell, ¡acostúmbrate!

Función explicada:

  • 1000<&0 1001>&1 1002>&2 aleja los primeros 3 FD
    • Esto supone que los FDs 1000, 1001 y 1002 son gratuitos.
  • 0</dev/tty 1>/dev/tty 2>&0 restaura los primeros 3 FD para apuntar a su TTY actual. Así que puedes controlar gdb .
  • /usr/bin/gdb -q -nx -nw ejecuta gdb invoca gdb en el shell
  • -ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\[email protected]\"" crea un contenedor de inicio, que restaura los 3 primeros FD que se guardaron en 1000 y más
  • -ex r inicia el programa usando el exec-wrapper
  • --args "[email protected]" pasa los argumentos dados.

¿No fue fácil?


Si lo hicieras desde un caparazón, lo harías así:

% gdb myprogram
gdb> run params ... < input.txt

Esto parece funcionar dentro de emacs también.







c++ debugging gdb