GDB veranlassen, eine Liste von Haltepunkten zu speichern


129

OK, info break listet die Haltepunkte auf, jedoch nicht in einem Format, das für die Wiederverwendung mit dem Befehl - wie in dieser Frage geeignet ist . Hat GDB eine Methode, um sie in eine Datei zu kopieren, die für eine erneute Eingabe akzeptabel ist? In einer Debugging-Sitzung muss GDB manchmal neu gestartet werden, nachdem eine Reihe von Haltepunkten zum Testen erstellt wurde.

Die .gdbinit-Datei hat das gleiche Problem wie --command. Der Befehl info break listet keine Befehle auf, sondern eine Tabelle für den menschlichen Verzehr.

Um dies zu erläutern, hier ein Beispiel aus der Infopause :

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

Antworten:


204

Ab GDB 7.2 (23.08.2011) können Sie jetzt den Befehl save breakpoints verwenden .

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.

Verwenden Sie source <filename>diese Option , um die gespeicherten Haltepunkte aus der Datei wiederherzustellen.


2
Was ist, wenn sie von einer gemeinsam genutzten lib-Last stammen? Es antwortet N standardmäßig, wie es scheint ...Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
bjackfly


Beachten Sie, dass break g_log if log_level==G_LOG_LEVEL_CRITICALmindestens gdb 7.8.1 das Parsen weiterer Befehle beendet , wenn Sie eine Haltepunktbedingung haben, die beim Start ( ) nicht behoben werden kann. Wenn Sie zusätzliche Befehle haben, die für diesen Haltepunkt ausgeführt werden sollen, setzen Sie die commandsZeile vor die conditionZeile.
Lekensteyn

@Andry Ich habe Ihre Bearbeitung auf mein ursprüngliches Blockzitat zurückgesetzt, da der Text ein wörtliches Zitat aus der Dokumentation ist. Ansonsten würde ich Ihrer Bearbeitung zustimmen, wenn es stattdessen meine eigenen Wörter wären.
Aculich

@aculich: Ich verstehe. Ich würde auf jeden Fall empfehlen, den Anführungszeichenstil anstelle des Codestils zu verwenden.
Andry

26

Diese Antwort ist veraltet. GDB unterstützt jetzt das direkte Speichern. Siehe diese Antwort .

Sie können die Protokollierung verwenden:

(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

Die Datei break.txt enthält jetzt:

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

Das Schreiben eines AWK-Skripts, das dies in ein für die Datei .gdbinitoder eine --commandDatei nützliches Format umwandelt, ist einfach. Oder Sie können das Skript sogar separat --eval-commandvon der GDB-Befehlszeile ausgeben lassen ...

Das Hinzufügen dieses kleinen Makros zu .gdbinit hilft Ihnen dabei:

# 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

Man könnte genauso gut Ausschneiden und Einfügen verwenden, aber die Skriptmethode scheint der richtige Weg zu sein.
Casualcoder

1
Ich denke nicht, dass Ausschneiden und Einfügen einfacher ist, als nur ein Skript einmal zu schreiben und es dann jedes Mal wieder zu verwenden :) Schließlich war das genau der Grund, warum Sie diese Frage überhaupt gestellt haben, denke ich :)
Johannes Schaub - litb

Ähm, ich meinte Ausschneiden und Einfügen anstelle der Protokollierungsmethode. Scripting ist es soweit sicher.
Casualcoder

Beeindruckend! gdb scheitern! Ich benutze es jeden Tag und liebe viele seiner Funktionen. Aber Mangel ist einfach nur dumm.
Deft_code

4
Diese Antwort ist jetzt älter als 2 Jahre und kann daher veraltet sein, wenn Sie eine neuere Version von gdb verwenden. Ab GDB 7.2 können Sie jetzt den save breakpointsBefehl verwenden.
Aculich

11

Fügen Sie Ihre GDB-Befehle und Haltepunkte so in eine .gdbinit-Datei ein, wie Sie sie möglicherweise an der gdb>Eingabeaufforderung eingeben , und GDB lädt sie beim Start automatisch und führt sie aus. Dies ist eine Verzeichnisdatei, sodass Sie unterschiedliche Dateien für unterschiedliche Projekte haben können.


1
Dies funktioniert tatsächlich nicht. Ich erhalte die Warnung: "Trace-Tracepoints speichern: Keine zu speichernden Tracepoints." Dies trotz gesetzter Haltepunkte. Mit GDB 6.8.
Casualcoder

Das funktioniert bei mir. GDB benötigt das Vorhandensein einer globalen .gdbinit in Ihrem $ HOME / .gdbinit mit dem Inhalt 'add-auto-load-safe-path /home/johnny/src/.gdbinit' und daher hat der Ordner src / auch eine separate .gdbinit
Truthadjustr

9

Eine Erweiterung von Anons Erweiterung zu Johannes 'Antwort :

.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

Mit können brestoreSie dann die mit gespeicherten Haltepunkte wiederherstellen bsave.


Hier ist eine bessere Regex: Perl -ne "print \" break \ $ 1 \ n \ "if /at\s(.*:\d+)/" brestore.txt
George Godik

6

Erweiterung der Antwort von Johannes : Sie können die Ausgabe von automatisch info breakin eine gültige GDB-Befehlsdatei umformatieren :

.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

Danach haben Sie eine gültige Befehlsdatei in brestore.gdb.

Dies hat bei mir funktioniert, wenn die Anwendung mit kompiliert wurde -g.

Ich habe es auch erfolgreich mit GDB v6.8 unter Ubuntu 9.10 (Karmic Koala) getestet .


1
Vielen Dank für diesen Ausschnitt! Funktioniert super. Erfolgreich getestet mit GNU gdb 6.3.50-20050815 (Apple Version gdb-966) in CarbonEmacs GNU Emacs 22.3.1 (i386-apple-darwin9.6.0, Carbon Version 1.6.0) unter Mac OS 10.5.8.
Pestophagous


3

Fügen Sie Folgendes in ~ / .gdbinit ein , um bsave und brestore als GDB-Befehle zum Speichern und Wiederherstellen von Haltepunkten zu definieren.

define bsave
    save breakpoints ~/.breakpoints
end

define brestore
   source ~/.breakpoints
end

1

Warnung: Das aktuelle Ausgabeprotokoll unterstützt keine Umleitung

Ich erhalte diesen Fehler / diese Warnung auch in GDB, wenn ich versuche, die Protokollierung im TUI- Modus zu aktivieren . Die Protokollierung scheint jedoch im "Nicht-TUI" -Modus zu funktionieren. Also verlasse ich den TUI-Modus, wenn ich etwas protokollieren möchte. (Mit Ctrl+X , Ctrl+A in den TUI-Modus wechseln .)

So arbeite ich:

  1. Starten Sie GDB (im normalen Modus)
  2. Protokollierung aktivieren: set logging on- Jetzt sollte es sich nicht beschweren.
  3. Schalten Sie in den TUI-Modus um und machen Sie GDB-Sachen
  4. wann immer ich etwas protokollieren möchte (wie einen riesigen Backtrace-Dump) - schalte in den normalen Modus um

Oh, und wenn Sie gerne "Bildschirm" verwenden (wie ich), wird es ein bisschen chaotisch, da es die gleichen Hotkeys verwendet.
Magnux

1

Ich fand den folgenden Zusatz zu einer vorherigen Antwort nützlich, um die Haltepunkte in einer bestimmten Datei zu speichern / laden.

  • Haltepunkte speichern: bsave {Dateiname}
  • Haltepunkte laden: Bload {Dateiname}

Fügen Sie wie in der vorherigen Antwort den folgenden Code zur Datei ~ / .gdbinit hinzu

# 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

Das Problem ist, dass das Festlegen eines Haltepunkts kontextsensitiv ist. Was ist, wenn Sie zwei statische Funktionen namens foo haben ?

Wenn Sie bereits eines der Module debuggen, die foo definieren, geht GDB davon aus, dass Sie dieses gemeint haben. Wenn Sie jedoch nur "break foo" in eine Datei kopieren und diese Datei beim Start lesen, ist nicht klar, welche Funktion foo Sie meinen.


0

Irgendwelche anderen Ideen? ich habe

warning: Current output protocol does not support redirection

nach dem

set logging on

BEARBEITEN:

Ich weiß, dass diese Frage lautet: "Wie speichere ich eine Liste von Haltepunkten?", Aber ich habe gerade festgestellt, dass wir mit GDB einfach Haltepunkte "in Datei gespeichert" setzen können

gdb> source breakpoints.txt

Wo breakpoints.txtist eine Datei wie diese:

break main.cpp:25
break engine.cpp:465
break wheel.cpp:57
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.