Break anywhere when $r1 equals to a certain string in GDB - gdb

Is there anyway to break on gdb when $r1 equals to a certain string I know there is :
break [addr] if ((int)strcmp($r1, "hello")) == 0
But what to set in addr when I just wanna break when the r1 is "hello" no matter the current function/address?

Related

gdb how to print variable name along with variable value like "$number = variable-name = variable-value"

By default, using p variable-name will display $num = variable-value, $num is the value history, but it there a way to print the variable name along with the variable value like $num = variable-name = variable-value?
I want this since I use
define p
set $i = 0
while $i < $argc
eval "print $arg%d", $i
set $i = $i + 1
end
end
in my ~/.gdbinit, to redefine p command so I can use p var1 var2 var3... to print multiple variables at once, but the print command only output $num = variable-value, and I don't know what the exact variable is in the output, the other situation is when I print the value history using just p $num, it is not that readable, I don't know the exact variable name.
NOTE: the variable may be int/char/pointer/array/vector/...
A solution could be to first add to the display list the wanted variables and then to display all of them together. Note that, it is needed to free the display list before with undisplay, otherwise it also prints the variables of the previous executions.
define p
set confirm off
eval "undisplay"
set confirm on
set $i = 0
while $i < $argc
eval "display $arg%d", $i
set $i = $i + 1
end
display
end
The undisplay evaluation is enclosed between set confirm off/on to suppress the following message:
[answered Y; input not from terminal]
If you have already set the confirm off option in your ~/gdbinit file, you will need to remove these two lines.
Edit: Honestly, I came to know about the display command finding a solution for this question. Although this answer might be useful to print multiple variables with their respective names, after several days using display in my workflow, I discourage to use this answer since I have come to the conclusion that display itself fits better at least my needs (printing multiple variables at every stop). Here the official doc:
If you find that you want to print the value of an expression frequently (to see how it changes), you might want to add it to the automatic display list so that GDB prints its value each time your program stops. Each expression added to the list is given a number to identify it; to remove an expression from the list, you specify that number. The automatic display looks like this:
2: foo = 38
3: bar[5] = (struct hack *) 0x3804
Basically, I have started using the command like this: I add a variable with display $var to the list of variables, and every time a breakpoint is reached the listed variables are automatically printed. It makes sense to have a feature like this in gdb. Thanks #CodyChan for the motivation.
In a nutshell, we want to output
$num = variable-name = variable-value
instead of
$num = variable-value
As far as I can tell, gdb adds to the value history in only three places: the print command, the call command, and the history-append! Scheme function. Since my Scheme is rusty, we'll need to use the CLI or Python to run print and modify its output.
Using the CLI
define pp
set $i = 0
while $i < $argc
eval "pipe print $arg%d | awk -v name='$arg%d' '{ if (NR == 1 && $2 == \"=\") { $2 = \"= \" name \" =\" }; print }'", $i, $i
set $i++
end
end
Pipe is new in gdb 10.
That awk command is, after unescaping,
awk -v name='$arg%d' '{ if (NR == 1 && $2 == "=") { $2 = "= " name " =" }; print }'
which changes the = (second field) in $num = variable-value to = variable-name = . If gdb's print command outputs more than one line, the NR == 1 in the awk command makes sure the substitution is only done on the first line.
Security note: gdb's pipe command appears to parse the shell_command into tokens and uses execve to run it, rather than passing it to an actual shell. This prevents some code injection attacks (if, for instance, the $arg%d in name='$arg%d' contains single quotes), but you should be careful of running any shell command comprised of text you haven't vetted.
Using Python
class PP(gdb.Command):
"""print value history index, name, and value of each arg"""
def __init__(self):
super(PP, self).__init__("pp", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION)
def invoke(self, argstr, from_tty):
for arg in gdb.string_to_argv(argstr):
line = gdb.execute("print " + arg, from_tty=False, to_string=True)
line = line.replace("=", "= " + arg + " =", 1)
gdb.write(line)
PP()
Here, we're using a more sed-like approach, using string.replace.
Sample session:
(gdb) set args a b c
(gdb) start
Starting program: /home/mp/argprint a b c
Temporary breakpoint 2, main (argc=4, argv=0x7ffffffee278) at argprint.c:4
4 for(int i=0; i < argc; i++) {
(gdb) pp i argc argv argv[0]#argc
$1 = i = 0
$2 = argc = 4
$3 = argv = (char **) 0x7ffffffee278
$4 = argv[0]#argc = {0x7ffffffee49f "/home/mp/argprint", 0x7ffffffee4b1 "a", 0x7ffffffee4b3 "b", 0x7ffffffee4b5 "c"}

Problem with Fortran substring comparison of different length

I am reading stdin in a loop and do some comparaison with a bunch of "if" to decide what to do according to the input.
Here is a shortened snippet of the code :
CHARACTER (len= :), allocatable :: input
CHARACTER (len=4096) :: inbuffer ! frustrating but... well, fortran :3
DO
! get input
READ(*, '(a)') inbuffer ! because apparently you can't have allocation on read so you can't just read "input". meh.
input = TRIM(inbuffer)
CALL debug_log(input)
IF(input .EQ. 'uci') THEN
CALL debug_log(" printing uci info")
!isready
ELSE IF(input .EQ. 'isready') THEN
CALL debug_log(" isready -> readyok")
WRITE(*, '(a)') "readyok"
!ucinewgame
ELSE IF(input .EQ. 'ucinewgame') THEN
CALL debug_log("not implemented : reset board and start a new game")
!position
ELSE IF(input(1:8) .EQ. 'position') THEN
CALL debug_log("not implemented : set position")
!quit -> exit main loop
ELSE IF(input .EQ. 'quit') THEN
CALL debug_log(" quit command issued, exiting main loop")
EXIT
!non uci command
!nothing yet
!unknown command
ELSE
CALL debug_log(" ignoring invalid command")
END IF
end do
The input will expect command like "position 123 23415 etc..."
If I type "posi" it's say it's an invalid command as expected.
If I type "position" it say it's not implemented as expected too.
However:
If I type "position": I get not implemented
Followed by "posi": it says "not implemented" instead of "invalid command"
My guess is that it read 8 character even if the input is only 4 and since the previous command was "position" it make posi + tion = position
Here is some log to demonstrate:
** opening debug file : 20181111 / 223418.127
223418.127 : Initializing Fortiche engine
223418.129 : Entering main loop
223420.859 : posi
223420.859 : ignoring invalid command
223426.467 : xxxxtion
223426.467 : ignoring invalid command
223430.498 : posi
223430.498 : not implemented : set position
223437.323 : xxxxxxxxx
223437.323 : ignoring invalid command
223439.418 : posi
223439.418 : ignoring invalid command
223443.979 : position
223443.979 : not implemented : set position
223447.122 : quit
223447.122 : quit command issued, exiting main loop
223447.122 : closing, bye
xxxxtion + posi = position
Which is clearly wrong but I can understand how it ended up like this.
Should I use something other than .EQ.?
When I print the input it clearly doesn't print the input + whatever garbage was left behind in memory. But it's doing it when comparing string of possibly different length.
What can I do to solve this problem?
I'm not even started with the hardcore parsing and I already have a problem.
I'm using GNU Fortran on Windows.
Yes, it's UCI stuff as Universal Chess Interface.
EDIT : Full source code : https://github.com/ker2x/fortiche (comment the dirty hack at line 107 & 108 to reproduce the problem)
Substring references need to have starting and ending positions that are within the limits of the string.
You don't defend against a string that has a length less than eight prior to the substring reference input(1:8) .eq. 'position'.
With input shorter than eight characters, your program is non-conforming, anything can then happen, where anything very reasonably includes the behaviour you see.
Runtime debugging options may help to catch this programming error, depending on the capabilities of your compiler.

Can gdb conditionally break non-interactively on function only if the function's return value is equal to "Value"?

I'm using gdb with the -x parameter in order to debug without having to interactively continue at each breakpoint.
[root#StackOverflow.com] $ cat gdb_cmds_01
b SomeSourceFile.cpp:123
commands
bt
cont
end
I'm then attaching to a process that uses SomeSourceFile.cpp in it's execution:
[root#StackOverflow.com] $ gdb -p 'pidof SomeRunningProgram' -x gdb_cmds_01
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-92.el6)
...
<GDB outputs a set S of backtraces as instructed by gdb_cmds_01>
Now, Let SomeSourceFile.cpp:123 contain a line like:
if (foo(person, &place, *time) == "Alice") { ... <do stuff > ... }
And then Suppose I want to break on SomeSourceFile:123 only if the return of foo(...) is not equal to "Alice".
Based on:
How to inspect the return value of a function in GDB?, I know that gdb can inspect the return value of a function.
And https://sourceware.org/gdb/onlinedocs/gdb/Break-Commands.html tells me that I can inspect the value of a variable non-interactively:
<...>
For example, here is how you could use breakpoint commands to print the value of x at entry to foo whenever x is positive.
break foo if x>0
commands
silent
printf "x is %d\n",x
cont
end
<...>
I have tried something like:
[root#StackOverflow.com] $ cat gdb_cmds_01
b SomeSourceFile.cpp:123 if foo(person, &place, *time) != "Alice"
commands
bt
cont
end
But GDB spits out:
gdb_cmds_01:1: Error in sourced command file:
No symbol "place" in current context.
Can this be worked around?
In order to break on SomeSourceFile.cpp:123 only when foo(...) != "Alice", can I also inspect the return value of a function non-interactively?
In other words, I want to see only a subset R of the set of backtraces S such that for all backtraces b in R, the return of foo(...) is always unequal to "Alice".
Suppose I want to break on SomeSourceFile:123 only if the return of foo(...) is not equal to "Alice".
This fairly easy to do if you go to the lower (assembly level), and if the code is built without optimization.
It is also trivial to do if you can modify the source like so:
if (foo(...) == "Alice") { ...
} else {
int x = 0; if (x) abort(); // break here
}
Now you can simply set breakpoint on line 125, and you are done.
So how can you do this without modifying the source?
You must understand that the compiler invokes some bool operator==(), compares the return to true or false, and conditionally jumps around the body of if when the condition is false.
The (gdb) info line 123 will give you range of instructions that were produced for this source line.
Disassembling that range of instructions will allow you to locate the call to operator==, and show you the instruction that compares EAX (JE or JNE) with 0 or 1.
You can then set the breakpoint on the conditional jump instruction, and use $EAX (or $RAX for 64-bit code) is the condition on that breakpoint.

How to print something without this format : $[num]=[value] in GDB environment?

What I want is this :
(gdb) define mynext
Redefine command "mynext"? (y or n) y
Type commands for definition of "mynext".
End with a line saying just "end".
>print "------"
>print Location:
>where
>print "-------------"
>print Code:
>list
>print "---------------------"
>print Next:
>next
>end
This is what outputs is:
$1 = "-----"
....
I expect:
-----
....
I used call printf("opopo") also, but It print the return value of "opopo" which is 5. Just like this:$4 = 5
My question is: how can I print something without this format which is :$[num]=[value].
As you found, print puts the printed value into the value history. gdb provides two different ways to avoid this.
One is printf. This works somewhat like the C function, but is a gdb command. Use it like:
(gdb) printf "whatever you like\n"
whatever you like
(gdb)
Another is output. This is a bit like the print command, but does not enter the value into the value history.
(gdb) output 5
5(gdb)
You can see from this that output also doesn't emit a trailing newline. You would have to add that yourself.

Possible output of the following program fragment?

for(i=getchar();; i=getchar())
if(i=='x')
break;
else putchar(i);
Answer is : mi
Can someone explain this piece of code ?(MCQ Question)
This question can be solved by eliminating incorrect answer. This fragments prints character and exits loop if the character is an x. So the program would not output an x.
Any output string that doesn't contain x is possible. In your MCQ, possibly mi is the only option with x and all other options contain x somewhere in the string making them incorrect answer.
If input is "mix....", output would be "mi". Below is your loop unrolled.
getchar() -> m -> else -> print m /* First getchar */
getchar() -> i -> else -> print i /* Second getchar */
getchar() -> x -> if -> break /* Second getchar */
for(i=getchar();; i=getchar())
if(i=='x')
break;
else putchar(i);
your Code will keep on running till it encounter 'x' so whatever input you give, it will read character by character as you have used getchar() function..
If character is 'x' then break the loop.
else print character.
like, If the input is
sparx
output will be
spar
The for loop
for(i=getchar();; i=getchar())
and syntax and structure of the for loop is
for ( variable initialization; condition; variable update )
as i = getchar() will read char 'i' it is ok. next there is no condition and final in updating you are again reading a character so it a infinite loop.
Loop will terminate only when it will encounter 'x' as the statement
if(i=='x')
break;
Otherwise it will keep on printing the character.
else putchar(i);
Here is the Demo.
Hope it helps!!