Je lance généralement un programme comme:
./a.out arg1 arg2 <file
Je voudrais le déboguer en utilisant gdb.
Je connais la set args
fonctionnalité, mais cela ne fonctionne qu'à partir de l'invite gdb.
Je lance généralement un programme comme:
./a.out arg1 arg2 <file
Je voudrais le déboguer en utilisant gdb.
Je connais la set args
fonctionnalité, mais cela ne fonctionne qu'à partir de l'invite gdb.
Réponses:
Passez les arguments à la run
commande depuis gdb.
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
$ gdb ./a.out
ce (gdb) r < t arg1 arg2
qui fonctionne bien pour moi. Dans mon cas a.out = nft
arg1 = import
arg2 = json
ett = file containing json rules
Tu peux le faire:
gdb --args path/to/executable -every -arg you can=think < of
Le morceau magique étant --args
.
Tapez simplement run
la console de commande gdb pour démarrer le débogage.
--args
, aucun argument n'est transmis à l'exécutable, ce n'est donc pas ambigu.
argv[0]
est le nom de l'exécutable
gdb
lui - même vers le of
fichier et fera en sorte que gdb essaie d'exécuter des commandes depuis celui
Si vous voulez avoir une run
commande nue gdb
pour exécuter votre programme avec des redirections et des arguments, vous pouvez utiliser set args
:
% gdb ./a.out
(gdb) set args arg1 arg2 <file
(gdb) run
Je n'ai pas pu obtenir le même comportement avec le --args
paramètre, gdb
échappe férocement aux redirections, c'est-à-dire
% gdb --args echo 1 2 "<file"
(gdb) show args
Argument list to give program being debugged when it is started is "1 2 \<file".
(gdb) run
...
1 2 <file
...
Celui-ci redirige en fait l'entrée de gdb lui-même, pas ce que nous voulons vraiment ici
% gdb --args echo 1 2 <file
zsh: no such file or directory: file
Démarrez GDB sur votre projet.
Accédez au répertoire du projet, où vous avez déjà compilé l'exécutable du projet. Exécutez la commande gdb et le nom de l'exécutable comme ci-dessous:
gdb projectExecutablename
Cela démarre gdb, imprime ce qui suit: GNU gdb (Ubuntu 7.11.1-0ubuntu1 ~ 16.04) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. ............... .................................. Tapez "mot approprié" pour rechercher des commandes liées à "mot" .. . Lecture des symboles depuis projectExecutablename ... done. (gdb)
Avant de lancer l'exécution de votre programme, vous souhaitez configurer vos points d'arrêt. La commande break vous permet de le faire. Pour définir un point d'arrêt au début de la fonction nommée main:
(gdb) b main
Une fois que vous avez l'invite (gdb), la commande run démarre l'exécution de l'exécutable. Si le programme que vous déboguez nécessite des arguments de ligne de commande, vous les spécifiez dans la commande d'exécution. Si vous vouliez exécuter mon programme sur le fichier "xfiles" (qui est dans un dossier "mulder" dans le répertoire du projet), vous feriez ce qui suit:
(gdb) r mulder / xfiles
J'espère que cela t'aides.
Avertissement: Cette solution n'est pas la mienne, elle est adaptée de https://web.stanford.edu/class/cs107/guide_gdb.html Ce petit guide de gdb a, très probablement, été développé à l'Université de Stanford.
Ne serait-il pas agréable de taper juste debug
devant une commande pour pouvoir la déboguer gdb
au niveau du shell?
En dessous, cette fonction. Il fonctionne même avec les éléments suivants:
"$program" "$@" < <(in) 1> >(out) 2> >(two) 3> >(three)
C'est un appel où vous ne pouvez rien contrôler, tout est variable, peut contenir des espaces, des sauts de ligne et des métacaractères shell. Dans cet exemple, in
, out
, two
et d' three
autres commandes arbitraires qui consomment ou produisent des données qui ne doivent pas être lésés.
La bash
fonction suivante invoque gdb
presque proprement dans un tel environnement [ Gist ]:
debug()
{
1000<&0 1001>&1 1002>&2 \
0</dev/tty 1>/dev/tty 2>&0 \
/usr/bin/gdb -q -nx -nw \
-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\"" exec' \
-ex r \
--args "$@";
}
Exemple d'application: il suffit de taper debug
devant:
Avant:
p=($'\n' $'I\'am\'evil' " yay ")
"b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
Après:
p=($'\n' $'I\'am\'evil' " yay ")
debug "b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
C'est tout. Maintenant, c'est une évidence pour déboguer gdb
. Sauf pour quelques détails ou plus:
gdb
ne se ferme pas automatiquement et maintient donc la redirection IO ouverte jusqu'à ce que vous quittiez gdb
. Mais j'appelle cela une fonctionnalité.
Vous ne pouvez pas facilement passer argv0
au programme comme avec exec -a arg0 command args
. Ce qui suit devrait faire cette astuce: après le exec-wrapper
changement "exec
de"exec -a \"\${DEBUG_ARG0:-\$1}\"
.
Il existe des FD au-dessus de 1000 ouverts, qui sont normalement fermés. Si c'est un problème, changez 0<&1000 1>&1001 2>&1002
pour lire0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-
Vous ne pouvez pas exécuter deux débogueurs en parallèle. Il peut également y avoir des problèmes si une autre commande consomme /dev/tty
(ou STDIN). Pour résoudre ce problème, remplacez /dev/tty
par "${DEBUGTTY:-/dev/tty}"
. Dans un autre type de TTY tty; sleep inf
, puis utilisez le TTY imprimé (i. E. /dev/pts/60
) pour le débogage, comme dans DEBUGTTY=/dev/pts/60 debug command arg..
. C'est le pouvoir de Shell, habituez-vous!
Fonction expliquée:
1000<&0 1001>&1 1002>&2
éloigne les 3 premiers FD
0</dev/tty 1>/dev/tty 2>&0
restaure les 3 premiers FD pour pointer vers votre ATS actuel. Vous pouvez donc contrôler gdb
./usr/bin/gdb -q -nx -nw
exécute gdb
invoque gdb
sur shell-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\""
crée un wrapper de démarrage, qui restaure les 3 premiers FD qui ont été enregistrés à 1000 et plus-ex r
démarre le programme en utilisant le exec-wrapper
--args "$@"
passe les arguments comme indiquéN'était-ce pas facile?
r
est l'abréviation derun
et vous pouvez le suivre avec n'importe quel argument. Comme dans cette question, ce serait:r arg1 arg2 <file
ou cela pourrait êtrerun arg1 arg2 <file