user41162
user41162

Reputation: 403

Invoke gdb to automatically pass arguments to the program being debugged

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

Answers (8)

crazy2be
crazy2be

Reputation: 2252

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!

Upvotes: 8

selalerer
selalerer

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

RandomNickName42
RandomNickName42

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

sdaau
sdaau

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

mike v
mike v

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

unwesen
unwesen

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

Nathan Fellman
Nathan Fellman

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

Adam Rosenfield
Adam Rosenfield

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

Related Questions