2008-11-26 14 views
38

Je voudrais écrire un script qui (sous certaines conditions) exécutera gdb et exécutera automatiquement un programme X avec un ensemble d'arguments Y. Une fois le programme terminé l'utilisateur doit rester à l'invite de gdb jusqu'à ce qu'il le quitte explicitement.Invoquer gdb pour passer automatiquement les arguments au programme en cours de débogage

Une façon de le faire serait d'avoir la sortie du script la commande d'exécution ainsi que les arguments Y pour certains fichiers F et alors l'invocation du script gdb comme ceci:

gdb X < F 

Mais est-il un moyen de faire ceci sans introduire un fichier temporaire?

Merci.

Répondre

26

Si vous voulez exécuter certaines commandes par GDB, puis l'ont sortie ou courir jusqu'à la fin, il suffit de

echo commands | gdb X 

Si vous voulez laisser à l'invite de commande après l'exécution de ces commandes, vous pouvez faire

(echo commands; cat) | gdb X 

Il en résulte en écho aux commandes de GDB, puis vous entrez dans le processus cat, qui copie son stdin stdout, qui est canalisé dans GDB.

+1

(echo "paramètres d'exécution", cat) | gdb X; # a travaillé un régal, merci beaucoup! –

+2

Notez que vous perdez l'interactivité du shell si vous le faites (toutes les fonctions d'édition readline, l'historique, etc.). – ijw

+0

Juste remarqué que haut/bas ne fonctionne pas .. pas une solution acceptable :( – Nils

0

cat F | gdb X doit être identique. Donc, vous pouvez utiliser tout ce qui produit une sortie et rediriger cela vers gdb au lieu de la commande cat ici.

Je suppose que vous avez raison et gdb lit à partir de stdin.

85

La meilleure façon de le faire étant donné un programme X et la liste des paramètres a b c:

X a b c 

est d'utiliser l'option de --argsgdb, comme suit:

gdb --args X a b c 

gdb --help A cela à propos de --args:

--args Arguments after executable-file are passed to inferior

Ce qui signifie que le premier argument après --args est l'exécutable à déboguer, et tous les arguments qui sont passés après comme il est à l'exécutable.

+0

J'ai eu un cas d'utilisation dans lequel dis une fonction foo (un , b, c) (tout type de données), cela a un appel dans le main(), maintenant je veux entrer ces arguments avant même que je commence à exécuter le programme .Peut-on y parvenir? – KedarX

+0

@Kedar: Pas de cette façon. La méthode détermine les arguments passés à 'main()'. C'est à vous de les transférer correctement à 'foo' –

+0

Ok, cela fait que mon doute est clair: il est impossible de donner des arguments à une méthode interne de main (à moins d'en faire par transfert)! Merci @Nathan Fellman – KedarX

1
gdb target -e "my-automation-commands" 

my-automatisation des commandes contenant tout ce que vous voulez normalement courir,

break 0x123 
set args "foo" bar 2 
r 

Pas strictement un fichier temporaire, si vous avez quelques scripts standards d'initialisation;)

8

il y a option -x, par exemple

gdb -x gdb_commands exe_file 

gdb_commands peuvent être par exemple (dans le cas de l'émulateur Android):

target remote :5039 
+2

Notez également que si vous voulez éviter d'utiliser un fichier temporaire, vous pouvez utiliser la substitution de processus: 'gdb -x <(echo commands) exe_file' –

+1

Il suffit d'utiliser 'gdb -ex 'foo' -ex 'bar'' pour lancer gdb avec les commandes' foo' puis 'bar'. – zopieux

1

Eh bien, cela est juste un commentaire, pas vraiment une réponse - je voulais juste d'inclure un code extraits. Je suis sur bash/Ubuntu Lucid - et pour moi, j'ai eu à peu près les mêmes problèmes que dans: "GDB has problems with getting commands piped to STDIN - Unix Linux Forum - Fixunix.com".

Fondamentalement, je voudrais obtenir le même que dans l'extrait suivant:

$ gdb 
GNU gdb (GDB) 7.1-ubuntu 
Copyright (C) 2010 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "i486-linux-gnu". 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>. 
(gdb) pwd 
Working directory /media/work/dir. 
(gdb) 

... sauf, je voudrais « pipe » la commande pwd en quelque sorte, et de garder gdb ouvert après (comme dans l'exemple ci-dessus).

J'ai essayé quelques-unes des suggestions ici, et la seule chose à travailler pour moi est la syntaxe (echo commands; cat) | gdb - ainsi que (travail peu) Here Strings - voici mes résultats:

$ echo "pwd" | gdb 
(gdb) Hangup detected on fd 0 
error detected on stdin 


$ echo "pwd" | gdb -x /dev/stdin 
GNU gdb (GDB) 7.1-ubuntu 
... 
/dev/stdin: Invalid argument. 
(gdb) Hangup detected on fd 0 
error detected on stdin 


$ gdb -x <(echo "pwd") 
GNU gdb (GDB) 7.1-ubuntu 
... 
/dev/fd/63: No such file or directory. 
(gdb) q 


$ gdb -e "pwd" 
GNU gdb (GDB) 7.1-ubuntu 
... 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>. 
(gdb) q # nothing happens 


$ gdb <<<"pwd" 
GNU gdb (GDB) 7.1-ubuntu 
... 
(gdb) Working directory /media/work/dir. 
(gdb) quit # OK, but autoexits 


$ gdb <<<"pwd 
> " 
GNU gdb (GDB) 7.1-ubuntu 
... 
(gdb) Working directory /media/work/dir. 
(gdb) Working directory /media/work/dir. 
(gdb) quit # with a line break at end, it execs twice, then exits 


# the only one OK for my needs - 
# except locks after quit, and needs Ctrl-C 
$ (echo "pwd"; cat) | gdb 
GNU gdb (GDB) 7.1-ubuntu 
... 
(gdb) Working directory /media/work/dir. 
(gdb) q 
^C 

Eh bien, l'espoir cela aide quelqu'un,
À votre santé!

 
Edit: Maintenant, au moins, je sais pourquoi la substitution de processus ne fonctionne pas - il utilisera un descripteur de fichier temporaire, qui ne peut être reconnu comme un fichier par ls (ainsi gdb lire peut certainement pas, en outre, la référence disparaît presque immédiatement, à moins que le processus est en quelque sorte bloqué, comme cat) - voir extrait de journal terminal:

$ echo -e "***\n" <(echo "pwd") "\n***\n`cat <(ls -C /dev/fd ; echo; for ix in /dev/fd/*; do irl=$(readlink -f $ix); echo $ix -\> $irl; ls -la $ix 2>&1; ls -la $irl 2>&1; echo '______'; done ; ls -C /dev/fd)`" 

*** 
/dev/fd/63 
*** 
0 1 2 3 63 

/dev/fd/0 -> /dev/pts/0 
lrwx------ 1 user user 64 2010-11-07 21:18 /dev/fd/0 -> /dev/pts/0 
crw--w---- 1 user tty 136, 0 2010-11-07 21:18 /dev/pts/0 
______ 
/dev/fd/1 -> /proc/10713/fd/pipe:[236191] 
l-wx------ 1 user user 64 2010-11-07 21:18 /dev/fd/1 -> pipe:[236151] 
ls: cannot access /proc/10713/fd/pipe:[236191]: No such file or directory 
______ 
/dev/fd/2 -> /dev/pts/0 
l-wx------ 1 user user 64 2010-11-07 21:18 /dev/fd/2 -> pipe:[236151] 
crw--w---- 1 user tty 136, 0 2010-11-07 21:18 /dev/pts/0 
______ 
/dev/fd/255 -> /proc/10721/fd/255 
ls: cannot access /dev/fd/255: No such file or directory 
ls: cannot access /proc/10721/fd/255: No such file or directory 
______ 
/dev/fd/3 -> /proc/10725/fd/3 
ls: cannot access /dev/fd/3: No such file or directory 
ls: cannot access /proc/10725/fd/3: No such file or directory 
______ 
0 1 2 3 

en outre, les touches haut/bas ne fonctionnent pas avec (echo commands; cat) | gdb, parce que c'est la façon dont le chat se comporte; si nous courons juste cat donc il copie stdin stdout, nous obtenons:

$ cat # or `cat -`: and start pressing up/down keys - and get: 
^[[A^[[B^[[A^[[B^[[A^[[B^C 

Vous pouvez essayer d'activer le mode caractère brut (ou désactiver tampon/mode de cuisson) avec stty -cooked, puis cat sera à la fois écrire des caractères comme ^[[A, et déplacer le curseur - malheureusement, dans ce mode, Ctrl-C ne fonctionne plus, donc vous ne serez pas en mesure de fermer cat de cette façon ...

1

Avec bash, vous pouvez créer un script qui donne à l'utilisateur une entrée similaire à tout fichier exécutable que vous exécutez:

#!/bin/sh 
gdb X <<GDB_INPUT 
pwd 
run X a b c 
quit 
GDB_INPUT 
+1

Comment puis-je faire gdb pour continuer à courir après cela, au lieu de quitter? .. Donc: gdb -ex run --args prog arg ... semble être la meilleure approche – Alex

+0

Il suffit de supprimer la commande "quitter". – selalerer

4

Après avoir essayé toutes les réponses ici,

  1. L'écho/hack chat, tout intelligent, casse quelques fonctionnalités importantes de gdb. Plus particulièrement, toutes les invites utilisateur reçoivent une réponse automatique (vous n'avez donc pas la possibilité de confirmer les opérations potentiellement dangereuses), et Ctrl + C (pour arrêter un processus que vous déboguez) finit par tuer le chat, vous ne pouvez donc pas réellement Parlez à gdb après ça. L'option -x est supposée fonctionner, mais je n'ai pas réussi à l'utiliser avec ma version de gdb, et elle nécessite un fichier temporaire.

Cependant, il se trouve que vous pouvez simplement utiliser -ex, comme ceci:

gdb -ex "target remote localhost:1234" 

Vous pouvez également spécifier plusieurs fois -Ex pour exécuter plusieurs commandes!