Comment passer des arguments et rediriger stdin d'un fichier vers le programme exécuté dans gdb?

J'exécute habituellement un programme comme:

./a.out arg1 arg2 <file

Je voudrais le déboguer en utilisant gdb.

Je suis conscient de la fonctionnalité set args, mais cela ne fonctionne qu'à partir de l'invite gdb.

205

5 réponses

Passez les arguments à la commande run depuis gdb.

$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
131
répondu marcog 2010-12-23 17:32:48

, Vous pouvez faire ceci:

gdb --args path/to/executable -every -arg you can=think < of

Le bit magique étant --args.

Tapez simplement run dans la console de commande gdb pour commencer le débogage.

405
répondu rubenvb 2014-05-28 14:53:40

Si vous voulez avoir la commande bare run dans 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

J'ai été incapable d'obtenir le même comportement avec --args paramètre gdb farouchement échappe à l'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 elle-même, pas ce que nous voulons vraiment ici

% gdb --args echo 1 2 <file
zsh: no such file or directory: file
3
répondu unkulunkulu 2017-05-11 11:26:54

Démarrez GDB sur votre projet.

  1. Allez dans le répertoire du projet, où vous avez déjà compilé l'exécutable du projet. Émettez 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 "apropos word" pour rechercher des commandes liées "word"... Lecture des symboles de projectExecutablename...faire. (gdb)

  1. Avant de commencer votre programme en cours d'exécution, 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 principal

  2. 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 à l'exécution commande. Si vous vouliez exécuter mon programme sur le fichier" xfiles " (qui se trouve dans un dossier "mulder" dans le répertoire du projet), vous feriez ce qui suit:

    (gdb) R mulder/xfiles

J'espère que cela aide.

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 été, très probablement, développé à L'Université de Stanford.

1
répondu Ehsan 2016-11-13 01:57:54

Ne serait-il pas agréable de taper debug devant n'importe quelle commande pour pouvoir le déboguer avec gdb au niveau du shell?

Ci-dessous cette fonction. Il fonctionne même avec ce qui suit:

"$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 flux de lignes et des méta-caractères shell. Dans cet exemple, in, out, two, et three sont arbitraires d'autres commandes qui consomment ou produisent des données qui ne doivent pas être lésés.

Suivant bash fonction appelle gdb près 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 sur la façon d'appliquer ceci: tapez simplement 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 ça. Maintenant, c'est une évidence absolue de déboguer avec gdb. Sauf pour quelques détails ou plus:

  • gdb ne quitte pas automatiquement et maintient donc la redirection D'E / S ouverte jusqu'à ce que vous quittiez gdb. Mais j'appelle cela un caractéristique.

  • Vous ne pouvez pas facilement passer argv0 pour le programme comme avec exec -a arg0 command args. Suivant devrait faire cette astuce: après exec-wrapper changer "exec à "exec -a \"\${DEBUG_ARG0:-\$1}\".

  • Il y a des FDs au-dessus de 1000 ouverts, qui sont normalement fermés. Si c'est un problème, modifiez 0<&1000 1>&1001 2>&1002 lire 0<&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}". Certaines autre type de TTY tty; sleep inf, puis utilisez le TTY imprimé (par exemple /dev/pts/60) pour le débogage, comme dans DEBUGTTY=/dev/pts/60 debug command arg... C'est le pouvoir de Shell, s'y habituer!

Fonction expliquée:

  • 1000<&0 1001>&1 1002>&2 éloigne les 3 premiers FDs
    • cela suppose que les FDs 1000, 1001 et 1002 sont libres
  • 0</dev/tty 1>/dev/tty 2>&0 restaure les 3 premiers FDs pour pointer vers votre TTY actuel. Vous pouvez donc contrôler gdb.
  • /usr/bin/gdb -q -nx -nw exécute gdb appelle gdb sur le 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 au-dessus
  • -ex r démarre le programme en utilisant exec-wrapper
  • --args "$@" transmet les arguments comme indiqué

N'était-ce pas facile?

0
répondu Tino 2018-09-02 16:10:46