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 argsfonctionnalité, 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 argsfonctionnalité, mais cela ne fonctionne qu'à partir de l'invite gdb.
Réponses:
Passez les arguments à la runcommande depuis gdb.
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
$ gdb ./a.outce (gdb) r < t arg1 arg2qui 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 runla 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
gdblui - même vers le offichier et fera en sorte que gdb essaie d'exécuter des commandes depuis celui
Si vous voulez avoir une runcommande nue gdbpour 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 --argsparamè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 debugdevant une commande pour pouvoir la déboguer gdbau 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, twoet d' threeautres commandes arbitraires qui consomment ou produisent des données qui ne doivent pas être lésés.
La bashfonction suivante invoque gdbpresque 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 debugdevant:
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:
gdbne 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 argv0au programme comme avec exec -a arg0 command args. Ce qui suit devrait faire cette astuce: après le exec-wrapperchangement "execde"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>&1002pour 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/ttypar "${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>&0restaure les 3 premiers FD pour pointer vers votre ATS actuel. Vous pouvez donc contrôler gdb./usr/bin/gdb -q -nx -nwexécute gdbinvoque gdbsur 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?
rest l'abréviation derunet vous pouvez le suivre avec n'importe quel argument. Comme dans cette question, ce serait:r arg1 arg2 <fileou cela pourrait êtrerun arg1 arg2 <file