Ottenere GDB per salvare un elenco di punti di interruzione


129

OK, l' interruzione di informazioni elenca i punti di interruzione, ma non in un formato che funzionerebbe bene riutilizzandoli usando il comando - come in questa domanda . GDB ha un metodo per scaricarli in un file accettabile per un nuovo input? A volte in una sessione di debug, è necessario riavviare GDB dopo aver creato una serie di punti di interruzione per i test.

Il file .gdbinit presenta lo stesso problema di --command. Il comando di interruzione delle informazioni non elenca i comandi, ma piuttosto una tabella per il consumo umano.

Per elaborare, ecco un esempio di interruzione di informazioni :

(gdb) interruzione informazioni
Num Tipo Disp Enb Indirizzo Cosa
1 punto di interruzione mantenere y 0x08048517 <foo :: bar (vuoto) +7>

Risposte:


204

A partire da GDB 7.2 (23-08-2011) è 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.

Utilizzare source <filename>per ripristinare i punti di interruzione salvati dal file.


2
che dire se provengono da un carico lib condiviso? Risponde a N di default sembra ...Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
bjackfly


Nota che quando hai una condizione di breakpoint che non può essere risolta all'avvio ( break g_log if log_level==G_LOG_LEVEL_CRITICAL), almeno gdb 7.8.1 smetterà di analizzare ulteriori comandi. Se hai comandi aggiuntivi che dovrebbero essere eseguiti per quel punto di interruzione, metti la commandslinea prima della conditionlinea.
Lekensteyn,

@Andry Ho riportato la tua modifica alla mia blockquote originale perché il testo è una citazione testuale dalla documentazione ... Altrimenti sarei d'accordo con la tua modifica se fossero le mie parole.
aculich,

@aculich: capisco. Consiglierei di usare lo stile di quotazione piuttosto che lo stile di codice in ogni caso.
Andry,

26

Questa risposta è obsoleta. GDB ora supporta il salvataggio diretto. Vedere questa risposta .

È 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 breaks.txt ora contiene:

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

Scrivere uno script AWK che lo trasforma in un formato utile per il file .gdbinito --commandè facile. Oppure potresti anche rendere l'emissione dello script separata --eval-commanddalla riga di comando GDB ...

L'aggiunta di questa piccola macro a .gdbinit ti 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

Si potrebbe usare altrettanto facilmente il taglia e incolla, ma il metodo di scripting sembra essere la strada da percorrere.
casualcoder,

1
non penso che tagliare e incollare sia più semplice che scrivere una sola volta una sceneggiatura, per poi riutilizzarla ogni volta :) dopo tutto, questa è stata la vera ragione per cui hai posto questa domanda in primo luogo, penso :)
Johannes Schaub - litb

Uhm, intendevo usare taglia e incolla invece del metodo di registrazione. Lo scripting è sicuro finora.
casualcoder,

Wow! gdb fallire! Lo uso tutti i giorni e adoro molte delle sue funzionalità. Ma la mancanza è semplicemente stupida.
deft_code

4
Questa risposta ora ha più di 2 anni, quindi potrebbe essere obsoleta se si utilizza una versione più recente di gdb. A partire da gdb 7.2 ora puoi usare il save breakpointscomando.
aculich,

11

Inserisci i tuoi comandi GDB e punti di interruzione in un file .gdbinit proprio come potresti digitarli al gdb>prompt e GDB li caricherà e li eseguirà automaticamente all'avvio. Questo è un file per directory, quindi puoi avere file diversi per progetti diversi.


1
Questo in realtà non funziona, ricevo "avviso: save-tracepoints: nessun tracepoint da salvare". Questo nonostante i breakpoint siano stati impostati Usando gdb 6.8
casualcoder

Questo funziona per me. GDB ha bisogno della presenza di un .gdbinit globale nel tuo $ HOME / .gdbinit con contenuto 'aggiungi-caricamento automatico-sicuro-percorso /home/johnny/src/.gdbinit' e quindi anche la cartella src / ha un .gdbinit separato
truthadjustr,

9

Un'estensione all'estensione di anon alla risposta di 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è quindi possibile ripristinare i punti di interruzione salvati con bsave.


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

6

Estensione alla risposta di Johannes : potresti riformattare automaticamente l'output di info breakin un file di comando GDB valido:

.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 hai un file di comando valido in brestore.gdb.

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

Ho anche testato con successo con GDB v6.8 su Ubuntu 9.10 (Karmic Koala).


1
Grazie per questo frammento! 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 versione 1.6.0) su Mac OS 10.5.8.
pestofago


3

Inserisci quanto segue in ~ / .gdbinit per definire bsave e brestore come comandi GDB per salvare e ripristinare i punti di interruzione.

define bsave
    save breakpoints ~/.breakpoints
end

define brestore
   source ~/.breakpoints
end

1

avviso: il protocollo di output corrente non supporta il reindirizzamento

Ricevo anche questo errore / avviso in GDB quando provo ad abilitare la registrazione in modalità TUI . Tuttavia, la registrazione sembra funzionare in modalità "non TUI". Quindi lascio la modalità TUI ogni volta che voglio registrare qualcosa. (Passa avanti e indietro in modalità TUI con Ctrl+X , Ctrl+A ).

Ecco come lavoro:

  1. avvia GDB (in modalità normale)
  2. abilita la registrazione: set logging on- ora non dovrebbe lamentarsi.
  3. attiva / disattiva la modalità TUI e fai cose GDB
  4. ogni volta che voglio registrare qualcosa (come un'enorme discarica di backtrace) - passare alla modalità normale

Oh, e se ti piace usare "screen" (come faccio io) diventerà un po 'confuso, dato che usa gli stessi tasti di scelta rapida.
Magnux,

1

Ho trovato utile la seguente aggiunta a una risposta precedente per salvare / caricare i punti di interruzione in un file specifico.

  • Salva punti di interruzione: bsave {nome file}
  • Carica punti di interruzione: carica {nome file}

Come nella risposta precedente, aggiungi 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

0

Il problema è che l'impostazione di un punto di interruzione è sensibile al contesto. Cosa succede se si dispone di due funzioni statiche denominate foo ?

Se stai già eseguendo il debug di uno dei moduli che definiscono foo, GDB supporrà che tu lo intendessi. Ma se hai appena dump "pausa foo" in un file e quindi leggere il file allo start-up, non sarà chiaro quale funzione foo vuoi dire.


0

Altre idee? Io ho

warning: Current output protocol does not support redirection

dopo

set logging on

MODIFICARE:

So che la domanda è "come salvare un elenco di punti di interruzione", tuttavia ho appena scoperto che con GDB possiamo semplicemente impostare i punti di interruzione "salvati nel file"

gdb> source breakpoints.txt

dove breakpoints.txtè un file come questo:

break main.cpp:25
break engine.cpp:465
break wheel.cpp:57
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.