2010-09-18 10 views
11

Uso uno script di debug che esegue diversi processi correlati in successione con il debugger. Attualmente sto usando -x per eseguire automaticamente più comandi (come run). Come posso fare in modo che gdb si chiuda automaticamente quando termina il processo di debug? L'aggiunta di un comando quit al file di comando causerà che il comando venga gestito non solo in caso di terminazione avvenuta con successo, ma anche quando si verificano errori (quando preferirei subentrare a quel punto).Fai gdb uscire automaticamente al termine con successo?

Ecco un estratto di quello che sta succedendo:

+ 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)

Contenuto del gdbbatch:

start 
b cpfs_log if level >= WARNING
+1

C'è una domanda duplicato StackOverflow con una risposta utile: http: // StackOverflow.it/a/8657833/431087 –

risposta

4

GDB ha un "linguaggio" diverso per interagire con i programmi automatizzati chiamato GDB/MI (dettagliato here) , ma sfortunatamente, non sembra che supporti i condizionali, e dovrebbe funzionare da altri programmi con analisi e ramificazioni. Così, sembra che aspettare è il più facile (o almeno un lavoro) Soluzione:

$ 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 } 
} 

Ho provato questo con i programmi semplici:

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

con i seguenti risultati:

$ ./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) 

In sostanza, è necessario analizzare l'output e il ramo utilizzando qualcos'altro. Ciò naturalmente funzionerebbe con qualsiasi altro programma in grado di gestire input/output di un altro processo, ma lo script previsto sopra dovrebbe iniziare, se non ti dispiace Tcl. Dovrebbe essere un po 'migliore, e aspettarsi il primo prompt (gdb), ma funziona grazie allo stdin buffering.

È inoltre possibile modificarlo per utilizzare tale interfaccia GDB/MI con l'argomento della riga di comando -i su GDB; i suoi comandi e output sono un po 'più facilmente analizzabili, se ti espanderai per aver bisogno di funzionalità più avanzate, come puoi vedere nella documentazione precedentemente collegata.

11

gdb imposta $_exitcode quando il programma termina con successo. È possibile fare uso di che - impostarlo su un valore improbabile all'inizio del vostro script, e solo quit alla fine se è cambiato:

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

(Impostazione $_exitcode ad un valore improbabile è un po 'brutto, ma altrimenti non sarà definito affatto se il programma non termina, e non sembra esserci alcun modo ovvio di chiedere "questa variabile è definita?" in un condizionale.)

+0

[Questo documento] (http://info2html.sourceforge.net/cgi-bin/info2html-demo/info2html? (gdb.info.gz) Convenience% 2520Fun) mostra come usare '_isvoid 'con' _exitcode' per evitare di impostarlo su "valori improbabili". –

8

Penso di avere trovato una soluzione completa alla tua domanda in relazione alla ricerca di qualcosa di simile in How to make gdb send an external notification on receiving a signal?. Nessuno degli altri ragazzi qui sembra aver menzionato o scoperto gdb hooks.

Sulla base del suggerimento di Matthew su $ _exitcode, questa è ora la mia app /.gdbinit che raggiunge esattamente il comportamento desiderato; normale uscire in caso di cessazione di successo e scendere a prompt di gdb, inviare e-mail, roba del genere su tutto il resto:

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 
Problemi correlati