How can GDB de-reference the same pointer in two different ways? - c++

I have two pointer variables that point at the same address:
(gdb) p a
$1 = (MyClass *) 0x7fd7251e58f8
(gdb) p store._head._ptr
$2 = (MyClass *) 0x7fd7251e58f8
But when I dereference them, I get different results:
(gdb) p *a
$3 = {<MyBase> = {_state = 0}, price = 1, quantity = 1,
arrivalTime = 1430087034755819, matchTime =
"-18:23:53.000\000\000\000\000\000\000\000\035"}
(gdb) p *store._head._ptr
$4 = {<MyBase> = {_state = 0}, price = 1, quantity = 1,
arrivalTime = 1430087034755819, matchTime =
"20150427-18:23:53.000"}
See the difference? It's only in the field matchTime. So I checked the relative offset of the field in both instances:
(gdb) p ((char*)&a->matchTime) - (char*)a
$5 = 28
(gdb) p ((char*)&store._head._ptr->matchTime) - (char*)store._head._ptr
$6 = 20
I can understand why I'd get a 20, since there's 3 32-bit integers, followed by a 64-bit integer, total of 3*4+8=20 bytes.
Clearly, GDB thinks that both pointer variables are of the same type name, MyClass*. But it clearly also thinks that each variable is of a different type!
How can I dig deeper? How can I even distinguish between each of the types?
UPDATE: The problem was a linker issue. The code was linking with the wrong version of the library and headers. That caused the pointer variable accessed through store._head._ptr to have the same (old) type information as the rest of the library code, while the pointer variable a had incompatible (newer) type information.
My question still stands, though. How did GDB know that there was a difference? How can I ask GDB which type it used for dereferencing?
Using ptype on each variable yielded the same output of MyClass* type information. But still GDB did different dereferencing on each pointer variable.
I tried using nm and objdump on the executable and library, but I couldn't use their output to distinguish between the different types.
So How can I query GDB in greater detail about the types and debug information it has about every variable?

Right, so we can see now that you invoked Undefined Behaviour. It is probably possible, with enough time and effort, to reproduce the problem and use the GDB source code to trace the precise sequence of events that led to the symptoms you witnessed. However, this could fill a (boring) PhD thesis and is utterly without merit. When you see strange, inconsistent behaviours like this, something is wrong and it is in your best interest to go finding the source of the UB before attempting any further diagnostics with the affected tool/output/mechanism.

Using ptype on each variable yielded the same output of MyClass* type information.
But using ptype *a and ptype *store._head._ptr should show the difference.

Related

Variable size in ELF file is different from size reported by GDB?

The ELF symtab table reports that my variable has size 16. In particular, after running readelf -s mybinary, I see the following output:
Num: Value Size Type Bind Vis Ndx Name
83: 0804a718 16 OBJECT LOCAL DEFAULT 25 myVar
However, when I open GDB to examine the size of myVar, I see the following output:
print sizeof(myVar)
$1 = 4
I am not sure where this discrepancy is arising from. For some background, I am using x86-32, and I do not have access to the source file, so I do not know the actual type of myVar.
You must have an old GDB version (older than 8.1).
From the GDB NEWS file:
*** Changes in GDB 8.1
...
GDB no longer assumes functions with no debug information return
'int'.
...
Similarly, GDB no longer assumes that global variables with no debug
info have type 'int', and refuses to print the variable's value
unless you tell it the variable's type:
(gdb) p var
'var' has unknown type; cast it to its declared type
(gdb) p (float) var
$3 = 3.14
As the text says, before 8.1 GDB treated any variable without debug info as having int type, and sizeof(int) is 4 on your system.
Online version of the NEWS has slightly different text:
GDB no longer makes assumptions about the type of symbols without
debugging information to avoid producing erroneous and often confusing results;
P.S.
I already tried this. Neither gives any extra information
When asking a question, it helps to supply all relevant info and state what you have already tried.
Stating the version of GDB you are using would have helped as well.

Find out the source file (line number) where a global variable was initialized?

I have pretty large C++ code base of a shared library which is messed up with complicated conditional macro spaghetti so IDE has troubles with that. I examined it with GDB to find the initial value of a global variable as follows:
$ gdb libcomplex.so
(gdb) p some_global_var
$1 = 1024
So I figured out the value the variable was initialized with.
QUESTION: Is it possible to find out which source file (and maybe line number) it was initialized at with GDB?
I tried list some_global_var, but it simply prints nothing:
(gdb) list some_global_var
(gdb)
So on x86 you can put a limited number of hardware watchpoints on that variable being changed:
If you are lucky, on a global you can get away with
watch some_global_var
But the debugger may still decide that is not a fixed address, and do a software watchpoint.
So you need to get the address, and watch exactly that:
p &some_global_var
(int*)0x000123456789ABC
watch (int*)0x000123456789ABC
Now, when you restart, the debugger should pop out when the value is first initialised, perhaps to zero, and/or when it is initialised to the unexpected value. If you are lucky, listing the associated source code will tell you how it came to be initialised. As others have stated you may then need to deduce why that line of code generated that value, which can be a pain with complex macros.
If that doesn't help you, or it stops many times unexpectedly during startup, then you should initially disable the watchpoint, then starti to restart you program and stop as soon as possible. Then p your global, and if it does not yet have the magic value, enable the watchpoint and continue. Hopefully this will skip the irrelevant startup and zoom in on the problem value.
You could use rr (https://rr-project.org/) to record a trace of the program, then you could reverse-execute to find the location. E.g.:
rr replay
(gdb) continue
...
(gdb) watch -l some_global_var
(gdb) reverse-continue

How to tell the gdb the value of the 'optimized out value' or make it infer the value?

There is a C++ this pointer that is an <optimized out> value, but up the call stack its value can be found.
How to tell gdb that this has that specific value? Can gdb look at the stack and infer it?
There is no way to do this in gdb, at least not in the form of having print this know which frame to inspect to find the value.
One simple work around is to use a convenience variable. For example something like:
(gdb) up 5
(gdb) set $mythis = this
(gdb) down 5
(gdb) print *$mythis
Another approach would be to write a "convenience function" (that's the term used in the gdb manual) to automate this. Convenience functions are written in Python and can do many things, such as look for symbols in other stack frames. So, for example, you could write a $_this function and use it like:
(gdb) print *$_this()
... not quite the same but maybe it would fit your needs.

What does <exp+6> mean in gdb?

I was debugging a C++ code using gdb. The program stopped due to a segmentation fault.
Program received signal SIGSEGV, Segmentation fault.
So I was trying to print out the value of variables to identify where the error is coming from. I have an array called 'ring' of type 'Link **', where Link is a class I defined. Each element in the array points to a 'Link *' variable. Here is the output when I print the first three elements of the 'ring' array.
(gdb) print ring[0]
$13 = (Link *) 0x8125290
(gdb) print ring[1]
$14 = (Link *) 0xb7e80b86 <exp+6>
(gdb) print ring[2]
$15 = (Link *) 0x8132e20
Why am I getting '' after the memory address when printing 'ring[1]'? What does it mean?
EDIT: Im using gdb 7.8 on Arch Linux (3.16.4-1-ARCH)
It means the pointer value is equal to the address of the exp symbol plus 6. It's just the debugger trying to be helpful—whenever it decodes any pointer value, it tries to see if the pointer happens to lie near any known symbols in the object code, and it prints out that information if so.
You might expect to see such notation when examining the disassembly of a function's code, e.g. in branch targets, but as a data pointer, that's very unusual (function pointers would tend to point directly at function symbols, not offset into them).
You almost certainly have some kind of memory corruption bug that just happens to produce that value as a side effect.

Setting GDB hardware watchpoint/how to set software watchpoint

An earlier question explained that on x86 the size of objects being watched is limited by debug registers. As expected, I can "watch" a double variable. But I can't watch a double datamember, for example,
watch pObject->dPrice
produces
Hardware watchpoint 1: pObject->dPrice
But when you try to continue execution, it says
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.
even though this is the only breakpoint/watchpoint.
I'm curious why this is so, but more importantly is there a way around it? According to GDB documentation it may use software watchpoints if it can't use hardware. In this case it makes no attempt to use a software watchpoint -- is there a way to force it to do so?
Yes, you can:
set can-use-hw-watchpoints 0
From 5.1.2 Setting Watchpoints:
You can force GDB to use only software watchpoints with the set can-use-hw-watchpoints 0 command. With this variable set to zero, GDB will never try to use hardware watchpoints, even if the underlying system supports them. (Note that hardware-assisted watchpoints that were set before setting can-use-hw-watchpoints to zero will still use the hardware mechanism of watching expression values.)
set can-use-hw-watchpoints
Set whether or not to use hardware watchpoints.
show can-use-hw-watchpoints
Show the current mode of using hardware watchpoints.
Short answer: Use watch -location pObject->dPrice, or the short form watch -l.
Long answer: Quoting the GDB manual:
Watching complex expressions that reference many variables can also exhaust the resources available for hardware-assisted watchpoints. That's because GDB needs to watch every variable in the expression with separately allocated resources.
GDB quite literally watches the expression itself, not whatever address it points to. In this case, it means that the breakpoint will hit if pObject itself is changed to point to a new dPrice; there's not just a watchpoint for pObject->dPrice, but also one for pObject itself. This may be more than what's available.
A more comprehensive example:
// Set a watchpoint on '*p' before running
#include <stdio.h>
int a = 0;
int b = 0;
int c = 0;
int* p = &a;
int main()
{
puts("Hi"); // Dummy lines to make the results clearer, watchpoints stop at the line after the change
*p = 1; // Breaks: *p was changed from 0 to 1
puts("Hi");
a = 2; // Breaks: a is *p, which changed from 1 to 2
puts("Hi");
p = &b; // Breaks: p is now b, changing *p from 2 to 0
puts("Hi");
p = &c; // Doesn't break: while p changed, *p is still 0
puts("Hi");
p = NULL; // Breaks: *p is now unreadable
puts("Hi");
return 0;
}
In theory, this is a useful feature; you can watch a complex expression, breaking as soon as it's false, somewhat like a constantly-tested assertion. For example, you can watch a==b in the above program.
In practice, it's unexpected, often triggers this issue, and usually isn't what you want.
To watch only the target address, use watch -location pObject->dPrice. (This is available as of GDB 7.3, released in July 2011; if you're using anything older, use print &pObject->dPrice and watch *(double*)0x12345678, or whichever address it prints.)
I'm not 100% sure, but my understanding is that when you watch pObject->dPrice, GDB tries to watch anything that can change the watched value.
Using software watchpoints, after each step GDB checks if the expression has changed. Using hardware watchpoints, GDB has to set a watchpoint for dprice, as you expect, but also for pObject.
Now, you tagged the question 'x86'. On x86 you can set breakpoints for up to four bytes. A double is eight bytes. If you want to watch a double, I would guess that GDB would need two hardware watchpoints. You need an additional watchpoint for pObject as well. I'm guessing that GDB tries to watch all of pObject, which goes back to the problem in the question you linked in the question.
When I want to do something similar, if I'm certain that the pointer pObject will not change, I usually do:
p &pObject->dprice
Let's say GDB says the address is (double *) 0xabcdef10, now I do:
watch (double *) *0xabcdef10
and watch only what I want to.
Note: I don't have GDB open in front of me, so I may have the exact syntax for the watch command wrong (regarding the placement of the *), so check it out first.