web-dev-qa-db-fra.com

Obtenir gdb pour enregistrer une liste de points d'arrêt?

OK, info break répertorie les points d'arrêt, mais pas dans un format qui fonctionnerait bien avec leur réutilisation à l'aide de la commande comme dans cette question . Gdb a-t-il une méthode pour les vider dans un fichier acceptable pour une nouvelle saisie? Parfois, lors d'une session de débogage, il est nécessaire de redémarrer gdb après avoir créé un ensemble de points d'arrêt pour les tests.

Edit: le fichier .gdbinit a le même problème que --command. La commande info break ne répertorie pas les commandes, mais plutôt un tableau pour la consommation humaine.

Pour élaborer, voici un exemple de pause info:

 (gdb) info break 
 Num Type Disp Enb Address What 
 1 point d'arrêt garder y 0x08048517 <foo :: bar (void) +7> 
121
casualcoder

Depuis gdb 7.2, vous pouvez maintenant utiliser la commande save breakpoints.

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.

Utilisation source <filename> pour restaurer les points d'arrêt enregistrés à partir du fichier.

191
aculich

Cette réponse est obsolète, gdb prend désormais en charge l'enregistrement direct. Voir cette réponse .

Vous pouvez utiliser la journalisation:

(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

Le fichier breaks.txt contient désormais:

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

Écrire un script awk qui le transforme en un format utile pour le .gdbinit ou un --command le fichier est facile. Ou vous pouvez même faire émettre le script séparément --eval-command à la ligne de commande gdb ...

L'ajout de cette petite macro à .gdbinit vous aidera à le faire:

# 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
26

Placez vos commandes et points d'arrêt gdb dans un fichier .gdbinit comme vous pourriez les taper dans gdb> Invite, et gdb les chargera et les exécutera automatiquement au démarrage. Il s'agit d'un fichier par répertoire, vous pouvez donc avoir différents fichiers pour différents projets.

11
Paul Beckingham

Une extension de l'extension d'Anon à la réponse de 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

Avec brestore, vous pouvez ensuite restaurer les points d'arrêt enregistrés avec bsave.

9
Dan Berindei

Extension à la réponse de Johannes: vous pouvez reformater automatiquement la sortie de info break dans un fichier de commandes gdb valide:

.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

Ensuite, vous avez un fichier de commandes valide dans brestore.gdb

Cela a fonctionné pour moi lorsque l'application est compilée avec -g.

EDIT : testé avec succès avec gdb v6.8 sur Ubuntu Karmic.

6
anon
3
Abel

mettez ce qui suit dans ~/.gdbinit pour définir bsave et brestore en tant que commandes gdb pour enregistrer et restaurer les points d'arrêt.

define bsave
    save breakpoints ~/.breakpoints
end

define brestore
   source ~/.breakpoints
end
3
badeip

Je sais que c'est un vieux fil mais il est apparu dans ma recherche Google pour m'aider à le faire. Je suis nouveau sur gdb et j'ai trouvé l'ajout suivant à la réponse ci-dessus utile pour enregistrer/charger les points d'arrêt dans un fichier spécifique.

  • Enregistrer les points d'arrêt: bsave {filename}
  • Charger les points d'arrêt: bload {filename}

Comme ci-dessus, ajoutez le code suivant au fichier ~/.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
1
Mark A

avertissement: le protocole de sortie actuel ne prend pas en charge la redirection

J'obtiens également cette erreur/avertissement dans GDB lorsque j'essaie d'activer la journalisation en mode TUI, mais la journalisation semble fonctionner en mode "non-TUI". Je quitte donc le mode TUI chaque fois que je veux me connecter. (Basculez d'avant en arrière en mode TUI avec CTRL-X, CTRL-A).

Voici comment je travaille:

  1. démarrer GDB (en mode normal)
  2. activer la journalisation: set logging on - maintenant il ne faut pas se plaindre.
  3. basculer d'avant en arrière en mode TUI et faire des trucs GDB
  4. chaque fois que je veux enregistrer quelque chose (comme un énorme vidage de trace) - basculer en mode normal

J'espère que cela vous aidera,/M: o)

1
Magnux

Le problème est que la définition d'un point d'arrêt est sensible au contexte. Et si vous avez deux fonctions statiques nommées foo? Si vous déboguez déjà l'un des modules qui définit foo, alors gdb supposera que vous vouliez dire celui-là. Mais si vous déposez simplement "break foo" dans un fichier puis lisez ce fichier au démarrage, il ne sera pas clair quelle fonction foo vous voulez dire.

Je n'ai pas les points de mod pour répondre, mais ce que vous faites est de rendre vos points d'arrêt explicites, en spécifiant le fichier source et le numéro de ligne. Si foo () est spécifié à la fois dans foo.c: 42 et dans bar.c: 1337

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

Sinon, spécifiez un point d'arrêt source qui ne se déclenche que si le programme s'exécute sous gdb. Voir Comment détecter si le processus en cours est exécuté par GDB?

0
badeip

D'autres idées? j'ai

warning: Current output protocol does not support redirection

après

set logging on

MODIFIER:

Je sais que la question est "comment enregistrer une liste de points d'arrêt", mais je viens de découvrir qu'avec gdb, nous pouvons simplement définir des points d'arrêt "enregistrés dans le fichier" en

gdb> source breakpoints.txt

où breakpoints.txt est un fichier comme celui-ci:

break main.cpp:25
break engine.cpp:465
break wheel.cpp:57
0
noisy

Le problème est que la définition d'un point d'arrêt est sensible au contexte. Et si vous avez deux fonctions statiques nommées foo? Si vous déboguez déjà l'un des modules qui définit foo, alors gdb supposera que vous vouliez dire celui-là. Mais si vous déposez simplement "break foo" dans un fichier puis lisez ce fichier au démarrage, il ne sera pas clair quelle fonction foo vous voulez dire.

0
Michael Snyder