2009-02-01 14 views
102

OK, l'interruzione di informazioni elenca i punti di interruzione, ma non in un formato che funzioni bene con il riutilizzo utilizzando il comando - as in this question. Gdb ha un metodo per scaricarli nuovamente in un file accettabile per l'input? A volte in una sessione di debug, è necessario riavviare gdb dopo aver creato una serie di punti di interruzione per il test.Ottenere gdb per salvare un elenco di punti di interruzione?

Modifica: il file .gdbinit ha lo stesso problema di --command. Il comando info break non elenca i comandi, ma piuttosto una tabella per il consumo umano.

Elaborare, ecco un esempio da informazioni pausa:

 
(gdb) info break 
Num Type   Disp Enb Address What 
1 breakpoint  keep y 0x08048517 <foo::bar(void)+7> 

risposta

165

A partire da gdb 7.2 è ora possibile utilizzare il comando salva punti di interruzione.

save breakpoints <filename> 
    Save all current breakpoint definitions to a file suitable for use 
    in a later debugging session. To read the saved breakpoint 
    definitions, use the `source' command. 
+0

Non ho visto questa risposta, lo verificherò. – casualcoder

+1

cosa succede se provengono da un carico di lib condivisa? Per impostazione predefinita, N risponde che sembra ... 'Interrompe il breakpoint sul carico futuro della libreria condivisa? (y o [n]) [rispose N; input non dal terminale] ' – bjackfly

+1

@bjackfly usa 'set breakpoint in sospeso' come descritto in [come rispondere a Y in gdb script] (http://stackoverflow.com/questions/11356138/how-to-answer-y-in -gdb-script) e [gdb: come impostare i breakpoint su future librerie condivise con un flag --command] (http://stackoverflow.com/questions/100444/gdb-how-to-set-breakpoints-on-future -shared-libraries-with-a-command-flag) – aculich

11

Mettere i comandi gdb e punti di interruzione in un file .gdbinit proprio come si potrebbe digitarli al gdb> prompt e gdb caricherà automaticamente ed eseguirli all'avvio. Questo è un file per directory, quindi puoi avere file diversi per progetti diversi.

+1

Questo in realtà non funziona, ricevo "warning: save-tracepoints: nessun tracepoints da salvare". Questo nonostante i punti di interruzione impostati. Utilizzo di gdb 6.8 – casualcoder

+0

Questo funziona per me. GDB richiede la presenza di un file .gdbinit globale nel tuo $ HOME/.gdbinit con contenuto 'add-auto-load-safe-path/home/johnny/src /.gdbinit 'e quindi la cartella src/ha anche un file .gdbinit separato – ifelsemonkey

24

Questa risposta è obsoleta, gdb ora supporta il salvataggio diretto. Vedi this answer.

È possibile utilizzare la registrazione:

(gdb) b main 
Breakpoint 1 at 0x8049329 
(gdb) info break 
Num  Type   Disp Enb Address What 
1  breakpoint  keep y 0x08049329 <main+16> 
(gdb) set logging file breaks.txt 
(gdb) set logging on 
Copying output to breaks.txt. 
(gdb) info break 
Num  Type   Disp Enb Address What 
1  breakpoint  keep y 0x08049329 <main+16> 
(gdb) q 

Il file contiene breaks.txt ora:

Num  Type   Disp Enb Address What 
1  breakpoint  keep y 0x08049329 <main+16> 

Scrivendo uno script awk che trasforma, che in un formato utile per la .gdbinit o un --command il file è facile. Oppure si può anche fare lo script emette separati s --eval-command' alla riga di comando gdb ...

L'aggiunta di questo piccolo macro per .gdbinit vi aiuterà a farlo:

# call with dump_breaks file.txt 
define dump_breaks 
    set logging file $arg0 
    set logging redirect on 
    set logging on 
    info breakpoints 
    set logging off 
    set logging redirect off 
end 
+0

Uno potrebbe altrettanto facilmente usare il "copia e incolla", ma il metodo di scripting sembra essere la strada da percorrere – casualcoder

+1

non penso tagliato e -paste è più facile che scrivere una sceneggiatura una volta sola, poi usarla di nuovo ogni volta :) dopo tutto, questa è stata la ragione per cui hai fatto questa domanda in primo luogo, penso :) –

+0

Um, volevo dire usare cut-and- incollare al posto del metodo di registrazione, lo scripting è per ora sicuro – casualcoder

0

Il problema è che l'impostazione di un il punto di rottura è sensato al contesto. Cosa succede se si dispone di due funzioni statiche denominate foo? Se si sta già eseguendo il debug di uno dei moduli che definisce foo, si deve eseguire il , quindi il gdb presupporrà che si intendesse quello. Ma se semplicemente scarichi "break foo" in un file e poi leggi quel file all'avvio, , non sarà chiaro quale funzione foo intendi.

6

estensione alla risposta da Johannes: si potrebbe riformattare automaticamente l'uscita di info break in un file valido di comando gdb:

.gdbinit: 

define bsave 
    shell rm -f brestore.txt 
    set logging file brestore.txt 
    set logging on 
    info break 
    set logging off 
    # reformat on-the-fly to a valid gdb command file 
    shell perl -n -e 'print "break $1\n" if /^\d+.+?(\S+)$/g' brestore.txt > brestore.gdb 
end 
document bsave 
    store actual breakpoints 
end 

Successivamente si hanno un commandfile valido brestore.gdb

Questo ha funzionato per me quando l'applicazione è compilata con -g.

EDIT: testato con successo con gdb v6.8 su Ubuntu Karmic.

+1

Grazie per questo snippet! Funziona alla grande. Testato con successo con GNU gdb 6.3.50-20050815 (versione Apple gdb-966) in CarbonEmacs GNU Emacs 22.3.1 (i386-apple-darwin9.6.0, Carbon Version 1.6.0) su Mac OS 10.5.8. – pestophagous

9

Un'estensione estensione di anon alla risposta Johannes':

.gdbinit: 

define bsave 
    shell rm -f brestore.txt 
    set logging file brestore.txt 
    set logging on 
    info break 
    set logging off 
    # reformat on-the-fly to a valid gdb command file 
    shell perl -n -e 'print "break $1\n" if /^\d+.+?(\S+)$/g' brestore.txt > brestore.gdb 
end 
document bsave 
    store actual breakpoints 
end 

define brestore 
    source brestore.gdb 
end 
document brestore 
    restore breakpoints saved by bsave 
end 

Con brestore si può quindi ripristinare i punti di interruzione salvati con bsave.

+0

Ecco una regex migliore: perl -ne "print \" break \ $ 1 \ n \ "if /at\s(.*:\d+)/" brestore.txt –

0

Altre idee? Io ho

warning: Current output protocol does not support redirection 

dopo

set logging on 

EDIT:

So che domanda è "come salvare un elenco di punti di interruzione", ma ho appena scoperto, che con gdb noi può semplicemente impostare i punti di interruzione "salvati nel file" di

gdb> source breakpoints.txt 

dove breakpoints.txt è il file in questo modo:

break main.cpp:25 
break engine.cpp:465 
break wheel.cpp:57 
1

avvertimento: protocollo di uscita in corrente non non supporta il reindirizzamento

Inoltre ottengo questo errore/avviso in GDB quando si tenta di abilitare la registrazione in modalità TUI, tuttavia la registrazione sembra funzionare quando in "non- TUI ". Quindi lascio la modalità TUI ogni volta che voglio registrare qualcosa. (Passare avanti e indietro in modalità TUI con CTRL-X, CTRL-A).

Ecco come io lavoro:

  1. inizio GDB (in modalità normale)
  2. abilitare la registrazione: set logging on - ora non dovrebbe lamentarsi.
  3. levetta back/indietro alla modalità di TUI e fare GDB roba
  4. whenver Voglio accedere qualcosa (come una enorme discarica backtrace) - passare alla modalità normale

Spero che questo aiuti, /M: o)

+0

Oh, e se ti piace usare "screen" (come Lo faccio) sarà un po 'disordinato, dal momento che utilizza gli stessi tasti di scelta rapida. – Magnux

3

messo quanto segue in ~/.gdbinit per definire BSAVE e brestore come gdb comandi per Salva- e ripristinare i punti di interruzione.

define bsave 
    save breakpoints ~/.breakpoints 
end 

define brestore 
    source ~/.breakpoints 
end 
0

Il problema è che l'impostazione di un punto di interruzione è contesto sensative. Cosa succede se si hanno due funzioni statiche chiamate pippo?Se stai già eseguendo il debug di in uno dei moduli che definiscono foo, gdb supporrà che intendi quello . Ma se semplicemente scarichi "break foo" in un file e poi leggi il file all'avvio, non sarà chiaro quale sia la funzione corrispondente a .

Non ho i punti mod per rispondere, ma quello che fai è rendere espliciti i punti di interruzione, specificando il file sorgente e il numero di riga. Se foo() è specificato in entrambi foo.c: 42, e in bar.c: 1337

break foo.c:42 
break bar.c:1337 

In alternativa, specificare un punto di interruzione in-source che attivano solo se il programma è in esecuzione in gdb. Vedi How to detect if the current process is being run by GDB?

1

So che questo è un thread vecchio ma è venuto nella mia ricerca su Google per aiutarmi a fare questo. Sono nuovo di gdb e ho trovato la seguente aggiunta alla risposta sopra utile per salvare/caricare i breakpoint su un file specifico.

  • Salva i punti di interruzione: BSAVE {nome}
  • punti di interruzione di carico: BLOAD {nome}

Come sopra aggiungere il seguente codice al file ~/.gdbinit

#Save breakpoints to a file 
define bsave 
    if $argc != 1 
     help bsave 
    else 
    save breakpoints $arg0 
    end 
end 
document bsave 
Saves all current defined breakpoints to the defined file in the PWD 
Usage: bsave <filename> 
end 

#Loads breakpoints from a file 
define bload 
    if $argc != 1 
     help bload 
    else 
     source $arg0 
    end 
end 
document bload 
Loads all breakpoints from the defined file in the PWD 
Usage: bload <filename> 
end