128

Question cribbed from here:

I have a program that takes input from stdin and also takes some parameters from command line. It looks like this:

cat input.txt > myprogram -path "/home/user/work"

I try to debug the code with gdb inside emacs, by M-x gdb, I try to load the program with the command:

gdb cat input.txt > myprogram -path "/home/user/work"

However, gdb does not like it.

Unfortunately I don't understand the solution and am not sure what to do beyond compiling with the -g option and running the command M-x gdb.

1
  • It's perhaps worthwhile to note that already the first command in the question (without trying to invoke gdb) doesn't work. That means instead of cat input.txt > myprogram -path "/home/user/work" OP probably meant to write: cat input.txt | myprogram -path "/home/user/work" which of course contains a useless invocation of cat and something like < input.txt myprogram -path "/home/user/work" would make more sense, instead. Commented Nov 16 at 12:08

7 Answers 7

161

If you were doing it from a shell you'd do it like this:

% gdb myprogram
gdb> run params ... < input.txt

This seems to work within emacs too.

Sign up to request clarification or add additional context in comments.

6 Comments

The redirection seems to work but I get some errors. Failed to read a valid object file image from memory. Program exited with code 042. Any ideas?
I figured it out. For some reason I typed void main(int argc, char *argv[]) instead of "int main..." and it slipped my eye. Anyways everything works fine now; thanks for your help!
A belated thank you - the gdb manual is a pain in the butt to dredge through.
On Windows using msys64 I get < and input.txt as argv arguments to my program :( I'll keep digging around these answers with my gdb 8.2.1 : stackoverflow.com/questions/3544325/…
It's not working. I invoked GDB with gdb a.out and run by r arg1 < input.txt, but it recognized arg1, < and input.txt as three arguments. It turns out that set startup-with-shell off is the culprit!
|
37

There are several ways to do it:

$ gdb myprogram
(gdb) r -path /home/user/work < input.txt

or

$ gdb myprogram
(gdb) set args -path /home/user/work < input.txt
(gdb) r

or

$ gdb -ex 'set args -path /home/user/work < input.txt' myprogram
(gdb) r

where the gdb run command (r) uses by default the arguments as set previously with set args.

6 Comments

When I try this with gdb in cygwin, it doesn't work. The "show args" command shows that I entered the args I wanted, but when I start the program with "r", the program waits until I type stuff instead of reading from the specified file.
@cardiffspaceman, well, I can't test it with Cygwin - perhaps their gdb version is somehow limited
Why not simply gdb -ex 'r -path /home/user/work < input.txt' myprogram in the third variant?
@Ruslan, works as well - using 'set args ...' just gives you the chance to interactively define some break points etc. before running the program
True, but you can also set the breakpoint non-interactively, e.g. gdb -ex 'b main' -ex 'r -path /home/user/work < input.txt' myprogram.
|
8

This is eleven years later, and this question has an answer already, but for someone just like me in the future, I just wanted to add some thing.

After you run gdb your_program, if you just type run < file_containing_input, the program will just run till the end, and you might not catch the problem, so before you do run < file_containing_input do a break. Something like this

$ gdb your_program
gdb> break main
gdb> run < file_containing_input

1 Comment

start < file-to-pipe-in also works.
4

For completeness' sake upon starting a debugging session there is also the --args option. ie)

gdb gdbarg1 gdbarg2 --args yourprog arg1 arg2 -x arg3

3 Comments

How would you redirect input.txt as an input to yourprog upon starting a debugging session like this?
@Peter: gdb --args yourprog.out input.txt
That only works if "yourprog" expects a file name to specify the input, not input redirection.
1

And if you do not need to debug from the very beginning you can also attach to an already running process by using:

$ gdb myprogram xxx

where xxx is the process id. Then you do not need to tell gdb the starting arguments.

1 Comment

You missed to answer to the question title, at the part "reading stdin". I would make a good comment somewhere if it were shorter.
1

I want to point to the technique with mkfifo as described here:

gdb - debugging with pipe

if you have a more complicated pipe than reading from just one file, such as:

cat jonesforth.f examples/defining-words.f - |./jonesforth

the mkfifo can be very convenient.

Comments

1

Getting inputs from char *argv[]

In bash:

$> ./myprogram -path "/home/user/work"

In gdb:

(gdb) run -path "/home/user/work"

Getting inputs from stdin

First way with cat :

In bash:

$> cat ./input.txt | ./program

In gdb:

(gdb) run < ./input.txt

Second way with a command :

In bash:

$> python -c 'print("input")' | ./myprogram 

In gdb:

(gdb) run < <(python -c 'print("input")')

With the bash process substitution <(cmd) trick.

If there is several readline:

In gdb:

(gdb) run < <(python -c 'print("readline1")'; python -c 'print("readline2")')

Source: https://www.labri.fr/perso/fleury/posts/security/payload-injection.html

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.