Reputation: 403
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?
Upvotes: 40
Views: 50128
Reputation: 2252
After trying all of the answers here,
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!
Upvotes: 8
Reputation: 3924
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
Upvotes: 1
Reputation: 5955
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 ;)
Upvotes: 1
Reputation: 38619
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...
Upvotes: 1
Reputation: 91
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
Upvotes: 9
Reputation:
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.
Upvotes: 0
Reputation: 127428
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.
Upvotes: 87
Reputation: 400146
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.
Upvotes: 28