web-dev-qa-db-fra.com

Appelez gdb pour passer automatiquement des arguments au programme en cours de débogage

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 devrait rester sur l'invite de gdb jusqu'à ce qu'il le quitte explicitement. .

Une façon de le faire serait que le script génère la commande d'exécution plus les arguments Y dans un fichier F, puis que le script invoque gdb comme ceci:

gdb X < F

Mais existe-t-il un moyen de le faire sans introduire de fichier temporaire?

Merci.

39
user41162

Si vous souhaitez exécuter certaines commandes via GDB, puis le quitter ou l'exécuter jusqu'à la fin, faites simplement

echo commands | gdb X

Si vous souhaitez le laisser à l'invite de commande après avoir exécuté ces commandes, vous pouvez le faire

(echo commands; cat) | gdb X

Cela entraîne l'écho des commandes vers GDB, puis vous tapez dans le processus cat, qui copie son stdin dans stdout, qui est canalisé dans GDB.

28
Adam Rosenfield

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

X a b c

Est d'utiliser gdb's --args option, comme suit:

gdb --args X a b c

gdb --help a ceci à dire sur --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 suivants sont passés tels quels à cet exécutable.

86
Nathan Fellman

il y a l'option - x, par ex.

gdb -x gdb_commands exe_file

gdb_commands peut être par exemple (dans le cas de Android):

target remote :5039
8
mike v

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

  1. Le hack echo/cat, bien qu'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 des opérations potentiellement dangereuses), et Ctrl + C (pour arrêter un processus que vous déboguez) finit par tuer cat, vous ne pouvez donc pas réellement parler à gdb après ça.
  2. L'option -x est censée fonctionner, mais je n'ai pas pu la faire fonctionner avec ma version de gdb, et elle nécessite un fichier temporaire.

Cependant, il s'avère que vous pouvez simplement utiliser -ex, comme ceci:

gdb -ex "target remote localhost:1234"

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

7
crazy2be
gdb target -e "my-automation-commands"

mes commandes d'automatisation contenant tout ce que vous voudriez normalement exécuter,

break 0x123
set args "foo" bar 2
r

Pas strictement un fichier temporaire, si vous avez quelques scripts init standard;)

1
RandomNickName42

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

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

Eh bien, ce n'est qu'un commentaire, pas vraiment une réponse - je voulais juste inclure des extraits de code. Je suis sur bash/Ubuntu Lucid - et pour moi, j'ai eu à peu près les mêmes problèmes que dans: " GDB a des problèmes pour obtenir des commandes dirigées vers STDIN - Forum Unix Linux - Fixunix.com ".

Fondamentalement, j'aimerais obtenir la même chose que dans l'extrait de code 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 que je voudrais "canaliser" la commande pwd d'une manière ou d'une autre, et garder gdb ouvert par la suite (comme dans l'exemple ci-dessus).

J'ai essayé certaines des suggestions ici, et la seule chose qui fonctionne pour moi est le (echo commands; cat) | gdb syntaxe - ainsi que (fonctionne quelque 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, j'espère que cela aide quelqu'un,
À votre santé!


Edit: Maintenant, je sais au moins pourquoi la substitution de processus ne fonctionnera pas - elle utilisera un descripteur de fichier temporaire, qui ne peut pas être reconnu comme un fichier par ls (( donc gdb ne peut certainement pas le lire; en outre, la référence disparaît presque immédiatement, sauf si le processus est en quelque sorte bloqué, comme avec cat) - voir le journal du terminal fragment:

$ 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

De plus, les touches haut/bas ne fonctionnent pas avec (echo commands; cat) | gdb, parce que c'est ainsi que se comporte le chat; si nous exécutons simplement cat pour qu'il copie stdin dans 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 le mode tampon/cuit ) avec stty -cooked, puis cat écriront tous les deux des caractères comme ^[[A, et déplacez le curseur - malheureusement, dans ce mode, Ctrl-C ne fonctionne plus, vous ne pourrez donc pas fermer cat de cette façon ...

1
sdaau

cat F | gdb X doit être identique. Vous pouvez donc utiliser tout ce qui produit une sortie et le canaliser dans gdb au lieu de la commande cat ici.

Je suppose que vous avez raison et que gdb lit depuis stdin.

0
unwesen