2010-09-18 15 views
11

Uso un script de depuración que ejecuta varios procesos relacionados en sucesión con el depurador. Actualmente estoy usando -x para ejecutar varios comandos automáticamente (como run). ¿Cómo puedo hacer que gdb salga automáticamente cuando el proceso depurado finaliza exitosamente? Agregar un comando quit al archivo de comando hará que ese comando se maneje no solo al finalizar con éxito, sino también cuando se producen errores (cuando prefiero asumir el control en ese punto).¿Habilita gdb automáticamente al finalizar con éxito?

He aquí un extracto de lo que está pasando:

+ gdb -return-child-result -x gdbbatch --args ./mkfs.cpfs /dev/loop0 
GNU gdb (GDB) 7.1-ubuntu 
Reading symbols from /home/matt/cpfs/mkfs.cpfs...done. 

Program exited normally. 
Breakpoint 2 at 0x805224f: file log.c, line 32. 
(gdb)

Contenido de gdbbatch:

start 
b cpfs_log if level >= WARNING
+1

Hay una pregunta Stackoverflow duplicado con una respuesta útil: http: // stackoverflow.com/a/8657833/431087 –

Respuesta

4

BGF tiene un "lenguaje" diferente para interactuar con programas automatizados llamada GDB/MI (detallado here) , pero desafortunadamente, no parece que admita condiciones, y se espera que se ejecute desde otros programas con análisis y bifurcación. Por lo tanto, parece que esperar es la solución más fácil (o al menos una de trabajo):

$ cat gdbrunner 
#!/usr/bin/expect -f 

#spawn gdb -return-child-result --args ./mkfs.cpfs /dev/loop0 
spawn gdb -return-child-result --args [lindex $argv 0] 

#send "start\n" 
#send "b cpfs_log if level >= WARNING" 
send "run\n" 

expect { 
    normally\.   { send "quit\n" } 
    "exited with code" { interact -nobuffer } 
} 

He probado esto con los programas simples:

$ cat prog1.c 
int main(void) { return 0; } 
$ cat prog2.c 
int main(void) { return 1; } 

con los siguientes resultados:

$ ./gdbrunner ./prog1 
spawn gdb -return-child-result --args ./prog1 
run 
(gdb) run 
Starting program: /home/foo/prog1 

Program exited normally. 
(gdb) quit 
$ ./gdbrunner ./prog2 
spawn gdb -return-child-result --args ./prog2 
run 
(gdb) run 
Starting program: /home/foo/prog2 

Program exited with code 01. 
(gdb) 

Básicamente, tiene que analizar el resultado y bifurcar usando algo más. Esto, por supuesto, funcionaría con cualquier otro programa capaz de manejar la entrada/salida de otro proceso, pero la secuencia de comandos de arriba debe comenzar, si no le importa Tcl. Debería ser un poco mejor y esperar el primer aviso (gdb), pero funciona debido al almacenamiento temporal stdin.

También puede modificarlo para usar esa interfaz GDB/MI con el argumento de línea de comandos -i para GDB; sus comandos y resultados son un poco más fáciles de analizar, si se expande para necesitar funciones más avanzadas, como puede ver en la documentación vinculada anteriormente.

11

gdb establece $_exitcode cuando el programa finaliza satisfactoriamente. Puede hacer uso de esa - la puso a un valor poco probable en el inicio de la secuencia de comandos, y sólo quit al final si ha cambiado:

set $_exitcode = -999 
# ... 
run 
# ... 
if $_exitcode != -999 
    quit 
end 

(Configuración $_exitcode a un valor probable es un poco feo, pero de lo contrario no se definirá en absoluto si el programa no finaliza, y no parece haber ninguna manera obvia de preguntar "¿está definida esta variable?" en un condicional.)

+0

[Este documento] (http://info2html.sourceforge.net/cgi-bin/info2html-demo/info2html? (gdb.info.gz) Convenience% 2520Funs) muestra cómo usar '_idvoid 'con' _exitcode' para evitar establecerlo en "valores improbables". –

8

Creo que tengo encontró una solución completa a su pregunta en relación con la búsqueda de algo similar en How to make gdb send an external notification on receiving a signal?. Ninguno de los otros chicos aquí parece haber mencionado o descubierto gdb hooks.

Basado en el consejo de Matthew sobre $ _exitcode, este es ahora mi app/.gdbinit que logra exactamente el comportamiento deseado; normal de dejar de fumar por la terminación exitosa y soltar a pronta GDB, enviar correo electrónico, lo que sea en todo lo demás:

set $_exitcode = -999 
set height 0 
handle SIGTERM nostop print pass 
handle SIGPIPE nostop 
define hook-stop 
    if $_exitcode != -999 
     quit 
    else 
     shell echo | mail -s "NOTICE: app has stopped on unhandled signal" root 
    end 
end 
echo .gdbinit: running app\n 
run 
Cuestiones relacionadas