gdb input redirection using cygwin - gdb

It seems that input redirection in gdb does not work in Cygwin e.g
(gdb) run < input.txt
Is there other way to redirect input in gdb of Cygwin??

Unfortunately this is not possible when running gdb in cygwin. The bug exists for a quote long time, but apparently it's a hard one to fix - and probably the gdb devs prefer spending time on features/issues relevant to more common environments (such as Linux).
There are various possible workarounds; I'd prefer the first one since it's the cleanest and also useful while not debugging / running on cygwin:
Add a command line argument, e.g. -f whatever with whatever being the filename to read from. If the argument is not present or set to -, read from stdin. The -f - option is optional of course but for arguments accepting filenames it's a common standard (as long as it makes sense) to handle - as "use stdin/out".
Use the gdb hack mentioned here to remap stdin to a manually opened file inside the application:
> gdb yourexecutable
(gdb) break main
(gdb) run
(gdb) call dup2(open("input.txt", 0), 0)
(gdb) continue
This sets a breakpoint on the main function, then executes the program which will break right after entering main. Then dup2 is used to replace the stdin fd (0) with a file descriptor of the input file.

Related

Is it possible to register commands to a breakpoint from within an external file in GDB?

GDB allows registering a set of commands to a specific breakpoint via commands NUM syntax. I need to register the set of commands for a specific breakpoint via an external file, by using a syntax something like the following:
commands ./main.c:18
silent
print buffer[0]
cont
end
commands ./io.c:29
silent
printf "Hello world %i\n", myvar1
cont
end
The commands path/to/file:XX syntax is made up by me. Because the NUM in commands NUM syntax requires exactly the breakpoint's runtime ID number (assigned by GDB), I can not use a deterministic syntax for that purpose.
I'm currently registering breakpoints via a text file with such a content:
break ./main.c:18
break ./io.c:29
and then issuing source breakpoints.txt command inside GDB. It seems that there is no way to register commands at the same time while registering a breakpoint:
(gdb) help break
Set breakpoint at specified line or function.
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]
PROBE_MODIFIER shall be present if the command is to be placed in a
probe point. Accepted values are -probe' (for a generic, automatically guessed probe type), -probe-stap' (for a SystemTap probe) or
`-probe-dtrace' (for a DTrace probe).
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of the selected
stack frame. This is useful for breaking on return to a stack frame.
THREADNUM is the number from "info threads".
CONDITION is a boolean expression.
Multiple breakpoints at one place are permitted, and useful if their
conditions are different.
Question
Is there any easy way to set some predetermined commands for a predetermined breakpoint from within a file?
If not, is there any equivalent way to pass the (gdb) info breakpoints output to a file or a program while pipe is not available in GDB (version 5.3)? Currently I'm trying a workaround by using logging feature for that purpose:
set logging file /tmp/breakpoints
set logging on
info breakpoints
set logging off
Is there any easy way to set some predetermined commands for a predetermined breakpoint from within a file?
Yes: if you use commands without NUM, the commands will apply to the last breakpoint set. So you want something like:
break main.c:18
commands
silent
print buffer[0]
cont
end

GDB: disable printing of current line after every step

The GNU gdb commandline debugger prints the line it is currently on after every step and next command. Consider the following gdb session where I step through some code:
...
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffd848)
at src/main.cc:3
3 int main(int argc, char **argv){
(gdb) next
4 Printf("Hello World\n"); // <--- disable this
(gdb)
5 printf("Hello World 2\n"); // <--- disable this
(gdb)
Is there a gdb setting to disable this printing? I know this is technically possible because the gdb TUI has exactly the behaviour i'm looking for (accessible through gdb command set enable tui).
Thanks!
I achieved it through redirection:
define n
set logging file /dev/null
set logging redirect on
set logging on
next
set logging off
display
end
I found that capturing the output of next did not work using gdb.execute (gdb's python API). I expect that this is the case because the source line is not printed by next itself, but by the stop event that is triggered.
There is no straightforward way to do this when using the gdb CLI. The code that handles printing the "stop" to the user does not check anything that the user can set.
One way you could try solving this would be to alias n to a command that runs the command using a different interpreter, like interpreter-exec tui next. I am not sure if this will actually work.
Another way to accomplish this would be to write a Python command named n that uses gdb.execute to invoke next -- while capturing the output and ignoring it. This approach is somewhat dangerous because sometimes you probably do want some of the stop message, just not the source display.
The best approach would be to modify gdb to add a new set command to disable the source printing. This is easy to do.

How can I use a variable name instead of addresses when debugging valgrind runs with gdb?

Let's say I'm debugging with valgrind and gdb by doing:
$ valgrind --vgdb-error=0 ./magic
...and then in a second terminal:
$ gdb ./magic
...
(gdb) target remote | /usr/lib/valgrind/../../bin/vgdb
If I want to examine the defined-ness of some memory, I can use:
(gdb) p &batman
$1 = (float *) 0xffeffe20c
(gdb) p sizeof(batman)
$2 = 4
(gdb) monitor get_vbits 0xffeffe20c 4
ffffffff
Using three commands to do one thing is kind of annoying, especially since I usually want to do this a few times for many different variables in the same stack frame. But if I try the obvious thing, I get:
(gdb) monitor get_vbits &batman sizeof(batman)
missing or malformed address
Is it possible to get gdb to evaluate &batman and sizeof(batman) on the same line as my monitor command?
But if I try the obvious thing, I get: missing or malformed address
This is from GDB doc (http://sourceware.org/gdb/onlinedocs/gdb/Connecting.html#index-monitor-1210) for the monitor cmd:
monitor cmd
This command allows you to send arbitrary commands
directly to the remote monitor. Since gdb doesn't care about the
commands it sends like this, this command is the way to extend gdb—you
can add new commands that only the external monitor will understand
and implement.
As you can see "gdb doesn't care about the commands it sends like this". It probably means that the command after monitor is not processed in any way and sent AS IS.
What you can do to evaluate your variable on the same line is to use user defined commands in gdb (http://sourceware.org/gdb/onlinedocs/gdb/Define.html). Define your own comand and use the eval gdb command to prepare your command with necessary values (http://sourceware.org/gdb/current/onlinedocs/gdb/Output.html#index-eval-1744):
define monitor_var
eval "monitor get_vbits %p %d", &$arg0, sizeof($arg0)
end
And then use it like this:
(gdb) monitor_var batman

How can I use GDB to get the length of an instruction?

The problem I am trying to solve is that I want to dynamically compute the length of an instruction given its address (from within GDB) and set that length as the value of a variable. The challenge is that I don't want any extraneous output printed to the console (e.g. disassembled instructions, etc.).
My normal approach to this is to do x/2i ADDR, then subtract the two addresses. I would like to achieve the same thing automatically; however, I don't want anything printed to the console. If I could disable console output then I would be able to do this by doing x/2i ADDR, followed by $_ - ADDR.
I have not found a way to disable the output of a command in GDB. If you know such a way then please tell me! However, I have discovered interpreter-exec and GDB/MI. A quick test shows that doing x/2i works on GDB/MI, and the value of $_ computed by the MI interpreter is shared with the console interpreter. Unfortunately, this approach also spits out a lot of output.
Does anyone know a way to either calculate the length of an instruction without displaying anything, or how to disable the output of interpreter-exec, thus allowing me to achieve my goal? Thank you.
I'll give an arguably cleaner and more extensible solution that's not really shorter. It implements $instn_length() as a new GDB convenience function.
Save this to instn-length.py
import gdb
def instn_length(addr_expr):
t = gdb.execute('x/2i ' + addr_expr, to_string=True)
return long(gdb.parse_and_eval('$_')) - long(gdb.parse_and_eval(addr_expr))
class InstnLength(gdb.Function):
def __init__(self):
super(InstnLength, self).__init__('instn_length')
def invoke(self, addr):
return instn_length(str(long(addr)))
InstnLength()
Then run
$ gdb -q -x instn-length.py /bin/true
Reading symbols from /usr/bin/true...Reading symbols from /usr/lib/debug/usr/bin/true.debug...done.
done.
(gdb) start
Temporary breakpoint 1 at 0x4014c0: file true.c, line 59.
Starting program: /usr/bin/true
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffde28) at true.c:59
59 if (argc == 2)
(gdb) p $instn_length($pc)
$1 = 3
(gdb) disassemble /r $pc, $pc + 4
Dump of assembler code from 0x4014c0 to 0x4014c4:
An alternative implementation of instn_length() is to use the gdb.Architecture.disassemble() method in GDB 7.6+:
def instn_length(addr_expr):
addr = long(gdb.parse_and_eval(addr_expr))
arch = gdb.selected_frame().architecture()
return arch.disassemble(addr)[0]['length']
I have found a suitable solution; however, shorter solutions would be preferred. This solution sets a logging file to /dev/null, sets to to be overridden if it exists, and then redirects the console output to the log file temporarily.
define get-in-length
set logging file /dev/null
set logging overwrite on
set logging redirect on
set logging on
x/2i $arg0
set logging off
set logging redirect off
set logging overwrite off
set $_in_length = ((unsigned long) $_) - ((unsigned long) $arg0)
end
This solution was heavily inspired by another question's answer: How to get my program name in GDB when writting a "define" script?.

How to read a input file with both argv and redirection from a input file

My program needs to accept three kinds of input commands below:
./Myprogram input.txt
./Myprogram < input.txt
./Myprogram
I'm thinking about using argc to check the number of arguments to resolve the first two situations (since redirection doesn't count as an argument). But then I stuck on the last case, which simply waits for an user input.
I'm wondering if there is a way to tell if a redirection is present in the shell command?
For a more complicated scenario such as a mix of redirection and argv forms (see below). Is there a way to do it or it's simply a bad design for taking user commands?
./Myprogram input1.txt input2.txt input3.txt
./Myprogram input1.txt < input2.txt input3.txt
./Myprogram
Any help will be much appreciated!
Z.Zen
Redirection will never be seen by your program as an argument. So in:
./Myprogram input.txt
./Myprogram < input.txt
./Myprogram
the second and third forms are identical. As for your second set of possibilities:
./Myprogram input1.txt input2.txt input3.txt
./Myprogram input1.txt < input2.txt input3.txt
./Myprogram
the second line is equivalent to:
./Myprogram input1.txt input3.txt < input2.txt
and it's also indistinguishable from:
./Myprogram input1.txt input3.txt
(the only different being where standard input actually comes from).
A typical way some programs handle mixed input from stdin and files specified on the command line is to accept "-" as a special filename meaning "use stdin as the input file at this position in the argument list". Many such programs will default to processing a singleton-list of "-" if the argument list is empty.
The basic algorithm is:
if (there are no arguments left after parsing options)
call_function(stdin);
else
{
foreach remaining argument
{
FILE *fp;
if (strcmp(argument, "-") == 0)
call_function(stdin);
else if ((fp = fopen(argument, "r")) == 0)
...error handling...
else
{
call_function(fp);
fclose(fp);
}
}
}
You could pass the file name to the 'call_function()' too, and sometimes I write the code with the output file stream specified. That function ('call_function()') is what processes one file - reading to the end of the file. It does not close the file; it was given an open file and should not close it.
The first 'if' deals with the I/O redirection case, of course.
I wrote, many years go, a function to handle this loop. It simplifies my life whenever I need to write a command in this 'UNIX filter' idiom - which is quite often. Along with a standardized error reporting package, it greatly simplifies life. Having it as a function also permits me to use variants on it, such as one that creates a backup of the file before it is overwritten, or which safely overwrites the file if the function completes successfully.
#R.. is correct for the usual cases.
If you want to have interactive behavior in case #3 but not #2, beyond letting the terminal buffer the user's input by line, you can use isatty (specifically isatty(0)) to determine whether there's a person on the other end.
This is not standard C, but neither is the notion of a terminal or a shell!
I'm wondering if there is a way to tell if a redirection is present in the shell command?
No. From your program's point of view there is no difference between these two cases:
./Myprogram < input.txt
./Myprogram
In both the cases the program is not taking any command line argument and would get it's input from the standard input.In the first case it's the shell that is connecting the contents of the file input.txt to the stdin of your program your program knows nothing about this.
It is possible to tell whether there is data to read by using select() on stdin. This will not tell you whether there is a redirection (you won't be able to tell when the file is empty, or when for some reason the user managed to put something on stdin before your program got a chance to test for it). Whether it works for your case or not depends on what you want to do in borderline cases.
Alternatively, you can use isatty() on stdin to find out if it's a tty or not. It's what most programs will do to find out whether they are interactive or not, and probably better in your case.
Now, you may notice that blocking waiting for user input in the third case is what all standard tools do, and is probably the behavior most users expect of your program too.