Passing stdin arguments to executable being debugged with gdb

Viewed 1896

I've read many questions/answers here on SO on this topic but none of the solutions worked... I want to pipe a string generated by perl to an executable being debugged by gdb. But I can't even pass an escaped hexadecimal character... I've tried the following "solutions":

1:

$ gdb ./a.out
(gdb) r "\x41"

2:

perl -e 'print "\x41"' > input.cmd
$ gdb ./a.out
(gdb) r < input.cmd

3:

$ gdb --args ./a.out "\x41"
(gdb) r

4:

$ gdb ./a.out
(gdb) set args "\x41"
(gdb) r

and I also tried many different combinations of escape characters ", /, \, ', ` ... none worked. Solution number 2 is discussed on many posts here on SO but I get "<" as an argument (gdb is escaping everything to a string)

I even tried to no avail to debug bash and set the executable as a minor but the bash crashes...

What am I missing? I'm using gdb 8.0.1 on macOS 10.13

UPDATE:

just tried on a linux machine and the solutions above work. I'm guessing the problem is with the bash/gdb interaction on macOS... any ideas?

UPDATE2:

SOLVED

definitely an issue with bash calls inside gdb on macOS, managed to workaround like this:

$ gdb --args ./a.out $(perl -e 'print "\x41"')
2 Answers

perl -e 'print "\x41"' > input.cmd

You could just do echo A > input.cmd

This:

2
(gdb) r < input.cmd

does exactly what you ask for (./a.out runs and receives a single character A on its stdin).

but none of the solutions worked...

You'll have to tell us how you came to that conclusion.

Update:

when I do (gdb) r < input.cmd gdb passes two strings as arguments < and input.cmd

If that is the case, you have a broken GDB, or (more likely) a broken $SHELL.

GDB simply invokes $SHELL -c './a.out < input.cmd', and expects your $SHELL to perform redirection. If your shell doesn't do that, all bets are off.

You can run GDB under dtruss -f and see what GDB does, and what your shell does.

SOLVED

definitely an issue with bash calls inside gdb on macOS, managed to workaround like this:

$ gdb --args ./a.out $(perl -e 'print "\x41"')

UPDATE - NOW REALLY SOLVED

@EmployedRussian was right, the problem was in the stdin passing through bash to gdb:

This is a problem with macOS Sierra: gdb can't start with a shell (bash) if SIP is enabled, so there are two ways of using gdb on Sierra:

Using gdb 8.0.1 on Sierra:

OPTION 1: Disable shell startup on gdb:

echo "set startup-with-shell off" >> ~/.gdbinit

when I installed and codesigned gdb I did this while following the official wiki (https://sourceware.org/gdb/wiki/BuildingOnDarwin) and since forgot. That was the reason I couldn't pass stdin to gdb.

OPTION 2: Disable SIP and leave shell startup enable

echo "set startup-with-shell on" >> ~/.gdbinit

reboot into Recovery and:

csrutil disable

This is obviously not recommended but it serves to illustrate where the problem is regarding gdb 8.0.1 usage on Sierra. Hopefully a gdb update will fix this.

Related