How to view binary content of a C++ integer in gdb? - c++

int main()
{
int a = 0;
}
I compile: g++ -std=c++14 -g test.cpp
Run program in gdb:
gdb ./a.out
(gdb) break main
(gdb) run
(gdb) next
What I have tried:
(gdb) print /t &a
That prints 11111111111111111111111111111111101110101111100
That doesn't look like the right number, I was expecting 0000....0000. How can I print binary values from the memory location of the integer variable a ?

You are trying to print the address of a which is in the stack frame of main and has nothing to do with its value. Try:
print /t a

Use p /x to print something in hex. Let us look after a has been set to 0.
(gdb) n
28 return(0);
(gdb) p a
$6 = 0
ok
(gdb) p /x a
$7 = 0x0
ok in hex
(gdb) p /x &a
$8 = 0x7fffffffe3dc
address of a in automatic memory (on the stack).
(gdb) p /t &a
$9 = 11111111111111111111111111111111110001111011100
looks like binary, and slightly different on my machine than yours. good.
(gdb) print /t &a
That prints 11111111111111111111111111111111101110101111100
That doesn't look like the right number?
33 1's at the front, and the last 4 bits are 0xc.
Mine looks correct compared to hex. 0x7fffffffe3dc.
I suspect yours is too.
If you were expecting a bunch of 0's. that would be the value of a, not the address of a
(gdb) p /t a
$10 = 0
gdb shrunk the results - 0 is indeed a bunch of 0's.

You could also see it using a gui like: https://github.com/cyrus-and/gdb-dashboard which I recommend if you don't have a lot of experience with gdb. Also a simple cheat sheet will be helpful to have at hand: http://darkdust.net/files/GDB%20Cheat%20Sheet.pdf

Related

Using gdb to decode hex data to struct

I have a hex stream of hex data that is printed like
0x3a45 0x1234 0x0352 (in real far longer)
I know that it is content in a struct. Is there a way in gdb to map this on the struct? Gdb seems only to accept single values for doing this.
Like:
(gdb) print (myStruct) 0x3a45 0x1234 0x0352
$1 = { a = 3a, b = 45, f = 0x1234, c = 03, e = 52}
In this case it's very simple but there is complex struct and the hex string is far larger.
I think there are a couple viable ways to do this in gdb.
The simplest way is to write the data into the inferior's memory somehow. It might look something like:
(gdb) set $mem = malloc(50) # number of bytes
(gdb) set $mem[0] = 0x72
(gdb) set $mem[1] = 0xff
# etc - you can find faster ways to do this
(gdb) print *(struct whatever *) $mem
Filling the memory is a pain, but this can be scripted. For example you can write a little shell script to convert the raw bytes into a sequence of set commands and then source it. Or you can just write a new gdb command in Python that automates it all.
gdb also has an extension to let one create an array on the command line, and do a kind of "reinterpret cast" on it. I found this method a bit less handy, because I could only make the array feature create arrays of int, not char. But anyhow, consider this little program:
struct x {
int a;
long b;
};
int main() {
struct x x = { 23, 97 };
return 0;
}
I start gdb and stop on the return, then examine the memory:
(gdb) p sizeof(int)
$1 = 4
(gdb) p sizeof(x)
$2 = 16
(gdb) x/4xw &x
0x7fffffffe240: 0x00000017 0x00007fff 0x00000061 0x00000000
(That second word is garbage because it is in the struct padding...)
Now we can recreate x by hand from the raw data:
(gdb) print {struct x}{0x17, 0x7fff, 0x61, 0}
$3 = {
a = 23,
b = 97
}
This expression uses two extensions to C expressions that gdb provides. First, {0x17, 0x7fff...} is a way to write an array. Second, {struct x} is a kind of "reinterpret cast" - it reinterprets the raw bytes of the value as named type.

GDB prints arbitrary values when round() function called during debugging a C++ program [duplicate]

This question already has answers here:
Why does gdb evaluate sqrt(3) to 0?
(5 answers)
Closed 6 years ago.
I am debugging a c++ (mex) program using gdb. In the code threre is a statement where a variable is assigned a rounded value of another variable. For instance:
x = round(y);
The assignment works correctly and when I call at the gdb prompt (gdb) print x, the correct value is printed. However, when I call (gdb) print round(y), a strange arbitrary number is printed.
Any idea what could be a source of this strange behaviour?
I was able to reproduce this oddity on Ubuntu. gdb is having trouble with the double input and double return value.
There appears to be an easy workaround however by calling __round.
(gdb) p round
$6 = {<text variable, no debug info>} 0x7ffff77f7460 <__round>
(gdb) p round(1.3)
$7 = -858993460
(gdb) p __round(1.3)
$8 = 1
(gdb) p __round
$9 = {double (double)} 0x7ffff77f7460
Note that gdb prototype for __round appears correct while the parameter type information is missing for round. As a result, it is appears that the input/output are considered as ints to round.
The man page for round says that if x is integral then it will be directly returned. If we assume that gdb is converting the double to an int then it explains the output.
11 double y = 1.3;
(gdb) n
13 int k = round(y);
(gdb) p /x round(y)
$28 = 0xcccccccd
(gdb) p /lx *(long*)&y
$29 = 0x3ff4cccccccccccd
(gdb)
So gdb is truncating the input value to 32-bit int and sending an int to round which sends it right back. Thus the lower word of the double is the output. Or perhaps it is truncating the return value to 32-bit with the same result.
As to why gdb doesn't have a proper prototype for round, I'm not sure.
Good question.

unexpected results for memory allocation with c malloc function

I have to allocate memory for 4 pointers to pointers on float (2D) over many iterations (6), but at the second iteration, malloc gives me the same address for two allocations. Code :
int i=0, a=0;
for(i=0;i<6;i++)
{
float** P_i=(float**) malloc(4*sizeof(float*));
for(a=0;a<4;a++) P_i[a]=(float*) calloc(4,sizeof(float));
for(a=0;a<4;a++) free(P_i[a]);
free(P_i);
}
Debugging with gdb :
(gdb) print i
$42 = 1
(gdb) set $pos=0
(gdb) print P_i[$pos++]
$51 = (float *) 0x804d500
(gdb) print P_i[$pos++]
$52 = (float *) 0x804d148
(gdb) print P_i[$pos++]
$53 = (float *) 0x804d4e8
(gdb) print P_i[$pos++]
$54 = (float *) 0x804d500
P_i[0] and P_i[3] point to the same address 0x804d500 and I can't find why :/
between the first for(a=0;a<4;a++) and the 2nd (before freeing)
My guess is that gdb breaks on last iteration of the loop, before the last calloc() call. If it's the case P_i[3] have the address of the previous iteration.
Btw, it's hard to use gdb when there's more than one statement per line.
With information available this can't be answered, but let me try.
The code seems ok. I can't reproduce your problem either.
You can't really put a breakpoint on a blank line. I guess that would put it on a line with free.
My guess is, your code was compiled with optimization enabled, which probably reordered things making sure you are not really sure where execution has stopped. Disable optimization and re-build (on GCC that would be -O0). Or show us the disassembly (including current PC where you print).
My run on Ubuntu gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4 built with -O0 -g, stopped on a line with free (before it was executed):
(gdb) print i
$1 = 0
(gdb) set $pos=0
(gdb) print P_i[$pos++]
$2 = (float *) 0x602040
(gdb) print P_i[$pos++]
$3 = (float *) 0x602060
(gdb) print P_i[$pos++]
$4 = (float *) 0x602080
(gdb) print P_i[$pos++]
$5 = (float *) 0x6020a0
(gdb) bt
#0 main () at malloc.c:12
(gdb) list
7 for(i=0;i<6;i++)
8 {
9 float** P_i=(float**) malloc(4*sizeof(float*));
10 for(a=0;a<4;a++) P_i[a]=(float*) calloc(4,sizeof(float));
11
12 for(a=0;a<4;a++) free(P_i[a]);
Does your source code exhibit a problem even if you build it separately (not a part of larger program)? Do you have custom calloc / malloc implemented? What does "nm your-executable|grep calloc" show? It should be something like this:
U calloc##GLIBC_2.2.5

GDB : compute double with print

I would like to make some computation with gdb when my program is at a breakpoint.
But here is my problem :
(gdb) call 2,6*2
$26 = 12
It doesn't compute at all double.
How can I say gdb to compute doubles ?
Thank you.
(gdb) call 2,6*2
$26 = 12
It doesn't compute at all double.
It's not supposed to: you gave the GDB call command a comma-expression, which it correctly evaluated.
You probably want:
(gdb) print 2.6 * 2
$1 = 5.1999999999999993
or
(gdb) call 2.6 * 2
$2 = 5.1999999999999993

Can I set a breakpoint on 'memory access' in GDB?

I am running an application through gdb and I want to set a breakpoint for any time a specific variable is accessed / changed. Is there a good method for doing this? I would also be interested in other ways to monitor a variable in C/C++ to see if/when it changes.
watch only breaks on write, rwatch let you break on read, and awatch let you break on read/write.
You can set read watchpoints on memory locations:
gdb$ rwatch *0xfeedface
Hardware read watchpoint 2: *0xfeedface
but one limitation applies to the rwatch and awatch commands; you can't use gdb variables
in expressions:
gdb$ rwatch $ebx+0xec1a04f
Expression cannot be implemented with read/access watchpoint.
So you have to expand them yourself:
gdb$ print $ebx
$13 = 0x135700
gdb$ rwatch *0x135700+0xec1a04f
Hardware read watchpoint 3: *0x135700 + 0xec1a04f
gdb$ c
Hardware read watchpoint 3: *0x135700 + 0xec1a04f
Value = 0xec34daf
0x9527d6e7 in objc_msgSend ()
Edit: Oh, and by the way. You need either hardware or software support. Software is obviously much slower. To find out if your OS supports hardware watchpoints you can see the can-use-hw-watchpoints environment setting.
gdb$ show can-use-hw-watchpoints
Debugger's willingness to use watchpoint hardware is 1.
What you're looking for is called a watchpoint.
Usage
(gdb) watch foo: watch the value of variable foo
(gdb) watch *(int*)0x12345678: watch the value pointed by an address, casted to whatever type you want
(gdb) watch a*b + c/d: watch an arbitrarily complex expression, valid in the program's native language
Watchpoints are of three kinds:
watch: gdb will break when a write occurs
rwatch: gdb will break wnen a read occurs
awatch: gdb will break in both cases
You may choose the more appropriate for your needs.
For more information, check this out.
Assuming the first answer is referring to the C-like syntax (char *)(0x135700 +0xec1a04f) then the answer to do rwatch *0x135700+0xec1a04f is incorrect. The correct syntax is rwatch *(0x135700+0xec1a04f).
The lack of ()s there caused me a great deal of pain trying to use watchpoints myself.
I just tried the following:
$ cat gdbtest.c
int abc = 43;
int main()
{
abc = 10;
}
$ gcc -g -o gdbtest gdbtest.c
$ gdb gdbtest
...
(gdb) watch abc
Hardware watchpoint 1: abc
(gdb) r
Starting program: /home/mweerden/gdbtest
...
Old value = 43
New value = 10
main () at gdbtest.c:6
6 }
(gdb) quit
So it seems possible, but you do appear to need some hardware support.
Use watch to see when a variable is written to, rwatch when it is read and awatch when it is read/written from/to, as noted above. However, please note that to use this command, you must break the program, and the variable must be in scope when you've broken the program:
Use the watch command. The argument to the watch command is an
expression that is evaluated. This implies that the variabel you want
to set a watchpoint on must be in the current scope. So, to set a
watchpoint on a non-global variable, you must have set a breakpoint
that will stop your program when the variable is in scope. You set the
watchpoint after the program breaks.
In addition to what has already been answered/commented by asksol and Paolo M
I didn't at first read understand, why do we need to cast the results. Though I read this: https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html, yet it wasn't intuitive to me..
So I did an experiment to make the result clearer:
Code: (Let's say that int main() is at Line 3; int i=0 is at Line 5 and other code.. is from Line 10)
int main()
{
int i = 0;
int j;
i = 3840 // binary 1100 0000 0000 to take into account endianness
other code..
}
then i started gdb with the executable file
in my first attempt, i set the breakpoint on the location of variable without casting, following were the results displayed
Thread 1 "testing2" h
Breakpoint 2 at 0x10040109b: file testing2.c, line 10.
(gdb) s
7 i = 3840;
(gdb) p i
$1 = 0
(gdb) p &i
$2 = (int *) 0xffffcbfc
(gdb) watch *0xffffcbfc
Hardware watchpoint 3: *0xffffcbfc
(gdb) s
[New Thread 13168.0xa74]
Thread 1 "testing2" hit Breakpoint 2, main () at testing2.c:10
10 b = a;
(gdb) p i
$3 = 3840
(gdb) p *0xffffcbfc
$4 = 3840
(gdb) p/t *0xffffcbfc
$5 = 111100000000
as we could see breakpoint was hit for line 10 which was set by me. gdb didn't break because although variable i underwent change yet the location being watched didn't change (due to endianness, since it continued to remain all 0's)
in my second attempt, i did the casting on the address of the variable to watch for all the sizeof(int) bytes. this time:
(gdb) p &i
$6 = (int *) 0xffffcbfc
(gdb) p i
$7 = 0
(gdb) watch *(int *) 0xffffcbfc
Hardware watchpoint 6: *(int *) 0xffffcbfc
(gdb) b 10
Breakpoint 7 at 0x10040109b: file testing2.c, line 10.
(gdb) i b
Num Type Disp Enb Address What
6 hw watchpoint keep y *(int *) 0xffffcbfc
7 breakpoint keep y 0x000000010040109b in main at testing2.c:10
(gdb) n
[New Thread 21508.0x3c30]
Thread 1 "testing2" hit Hardware watchpoint 6: *(int *) 0xffffcbfc
Old value = 0
New value = 3840
Thread 1 "testing2" hit Breakpoint 7, main () at testing2.c:10
10 b = a;
gdb break since it detected the value has changed.