40

I'd like to write a script that (under certain conditions) will execute gdb and automatically run some program X with some set of arguments Y. Once the program has finished executing the user should remain at gdb's prompt until s/he explicitly exits it.

One way to do this would be to have the script output the run command plus arguments Y to some file F and then have the script invoke gdb like this:

gdb X < F

But is there a way to do this without introducing a temporary file?

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
user41162
  • 403
  • 1
  • 4
  • 4

8 Answers8

87

The easiest way to do this given a program X and list of parameters a b c:

X a b c

Is to use gdb's --args option, as follows:

gdb --args X a b c

gdb --help has this to say about --args:

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

Which means that the first argument after --args is the executable to debug, and all the arguments after that are passed as is to that executable.

Nathan Fellman
  • 122,701
  • 101
  • 260
  • 319
  • I had one use case wherein say some function foo(a,b,c) (any data type), this has a call in say main(), now I want to input this arguments even before I start executing the program. Can we achieve this? – KedarX Oct 08 '10 at 06:18
  • @Kedar: Not this way. This method determines the arguments passed to `main()`. It's up to you to transfer them properly to `foo`. – Nathan Fellman Oct 08 '10 at 09:36
  • Ok, that make my doubt clear; that there is no way we can feed arguments to any internal method inside main (unless done some by transfer)! Thanks @Nathan Fellman – KedarX Oct 08 '10 at 09:50
  • 12
    You can even `gdb -ex run --args prog arg...` to have the program starts automatically – Mildred Mar 31 '11 at 09:31
28

If you want to run some commands through GDB and then have it exit or run to completion, just do

echo commands | gdb X

If you want to leave it at the command prompt after running those commands, you can do

(echo commands; cat) | gdb X

This results in echoing the commands to GDB, and then you type into the cat process, which copies its stdin to stdout, which is piped into GDB.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • 1
    (echo "run params"; cat) | gdb X; # worked a treat, many thanks! – Ian Vaughan Sep 29 '10 at 12:58
  • 2
    Note that you lose the shell interactivity if you do that (all the readline editing features, history, etc.). – ijw Nov 04 '10 at 20:31
  • Just noticed that up/down doesn't work.. not an acceptable solution :( – Nils Nov 06 '10 at 10:47
  • 1
    @ijw, @Nils: You are correct. See mike v's answer (http://stackoverflow.com/questions/322110/invoke-gdb-to-automatically-pass-arguments-to-the-program-being-debugged/2717992#2717992) for a better solution. – Adam Rosenfield Nov 06 '10 at 22:01
9

there is option -x, e.g.

gdb -x gdb_commands exe_file

where gdb_commands can be for example (in the case of android emulator):

target remote :5039
mike v
  • 91
  • 1
  • 1
9

After trying all of the answers here,

  1. The echo/cat hack, while clever, breaks quite a few important features of gdb. Most notably, all user prompts are answered automatically (so you don't get a chance to confirm potentially dangerous operations), and Ctrl+C (to stop a process that you are debugging) ends up killing cat, so you can't actually talk to gdb after that.
  2. The -x option is supposed to work, but I couldn't get it to work with my version of gdb, and it requires a temporary file.

However, it turns out you can just use -ex, like this:

gdb -ex "target remote localhost:1234"

You can also specify -ex multiple times to run multiple commands!

crazy2be
  • 2,134
  • 1
  • 21
  • 17
1

With bash you can create a script that give user like input to any executable you're executing:

#!/bin/sh
gdb X <<GDB_INPUT
pwd
run X a b c
quit
GDB_INPUT
selalerer
  • 3,766
  • 2
  • 23
  • 33
  • 1
    How can I make gdb to continue to run after that, instead of quiting ? .. So: gdb -ex run --args prog arg... seems to be the better approach – Alex Nov 11 '13 at 14:41
1
gdb target -e "my-automation-commands"

my-automation-commands containing anything you would normally want to run,

break 0x123
set args "foo" bar 2
r

Not strictly a temp file, if you have a few standard init scripts ;)

Nathan Fellman
  • 122,701
  • 101
  • 260
  • 319
RandomNickName42
  • 5,923
  • 1
  • 36
  • 35
1

Well, this is just a comment, not really an answer - just wanted to include some code snippets. I'm on bash/Ubuntu Lucid - and for me, I had pretty much the same problems as in: "GDB has problems with getting commands piped to STDIN - Unix Linux Forum - Fixunix.com".

Basically, I'd like to achieve the same as in the following snippet:

$ 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) 

... except, I'd like to "pipe" the pwd command somehow, and keep gdb open afterwards (as in example above).

I've tried some of the suggestions here, and the only thing working for me is the (echo commands; cat) | gdb syntax - as well as (somewhat working) Here Strings - here are my results:

$ 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 

Well, hope this helps someone,
Cheers!

 
Edit: Now at least I know why process substitution will not work - it will use a temporary file descriptor, which cannot be recognized as a file by ls (thus gdb definitely cannot read it; additionally, the reference disappears almost immediately, unless the process is somehow blocked, as with cat) - see terminal log snippet:

$ 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

Also, the up/down keys fail to work with (echo commands; cat) | gdb, because that is how cat behaves; if we just run cat so it copies stdin to stdout, we get:

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

You may try to turn on raw character mode (or turn off buffered/cooked mode) with stty -cooked, and then cat will both write characters as ^[[A, and move the cursor - unfortunately, in this mode, Ctrl-C doesn't work anymore, so you won't be able to close cat in that way...

sdaau
  • 36,975
  • 46
  • 198
  • 278
0

cat F | gdb X should be identical. So you can use anything that produces output and pipe that into gdb instead of the cat command here.

I'm assuming you're correct and gdb reads from stdin.

Nathan Fellman
  • 122,701
  • 101
  • 260
  • 319