c++ - archivos - ¿Cómo pasar argumentos y redirigir la entrada estándar de un archivo a un programa ejecutado en gdb?
archivos en c (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.
¿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" "$@" < <(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 /"/$@/"" exec'' /
-ex r /
--args "$@";
}
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 degdb
. Pero llamo a esto una característica.No puede pasar fácilmente
argv0
al programa como con elexec -a arg0 command args
. Lo siguiente debería hacer este truco: después de queexec-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 leer0<&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 TTYtty; sleep inf
tty; sleep inf
y luego use el TTY impreso (i. E./dev/pts/60
) para la depuración, como enDEBUGTTY=/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 controlargdb
. -
/usr/bin/gdb -q -nx -nw
ejecutagdb
invocagdb
en el shell -
-ex ''set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 /"/$@/""
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 elexec-wrapper
-
--args "$@"
pasa los argumentos dados.
¿No fue fácil?
Inicie GDB en su proyecto.
Vaya al directorio del proyecto, donde ya ha compilado el ejecutable del proyecto. Ejecute el comando gdb y el nombre del ejecutable como se muestra a continuación:
gdb projectExecutablename
Esto inicia gdb, imprime lo siguiente: GNU gdb (Ubuntu 7.11.1-0ubuntu1 ~ 16.04) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. ............... .................................. Escriba "apropo word" para buscar comandos relacionados con "word" .. Lectura de símbolos de projectExecutablename ... hecho. (gdb)
Antes de iniciar su programa en ejecución, desea configurar sus puntos de interrupción. El comando break le permite hacerlo. Para establecer un punto de interrupción al principio de la función denominada principal:
(gdb) b principal
Una vez que tenga el indicador (gdb), el comando de ejecución inicia la ejecución del ejecutable. Si el programa que está depurando requiere argumentos de línea de comandos, especifíquelos al comando de ejecución. Si quisiera ejecutar mi programa en el archivo "xfiles" (que está en una carpeta "mulder" en el directorio del proyecto), haría lo siguiente:
(gdb) r mulder / xfiles
Espero que esto ayude.
Descargo de responsabilidad: esta solución no es mía, está adaptada de https://web.stanford.edu/class/cs107/guide_gdb.html Esta guía breve de gdb fue, probablemente, desarrollada en la Universidad de Stanford.
Pase los argumentos al comando de run
desde gdb.
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
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.
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