gdb "Invalid binary operation on numbers" - gdb

At work, while debugging our program with gdb, it sometimes repsonds to
a simple "next" command with "Invalid binary operation on numbers".
Mighty annoying. Googling finds absolutely no hints. It is C++, so
perhaps that has something inside gdb confused in some way; I have no
clue.
Anyone?
(I can't get formatting to work right as a comment, so I'm adding to this area)
257 SingleBitBusMap::const_iterator sbb = fSingleBitBusMap.find(constituents.first.c_str());
(gdb) next
Invalid binary operation on numbers.
(gdb)
fSingleBitBusMap is a std::map
constituents is a std::pair
constituents.first is a std::string
and, after it says "Invalid binary operation on numbers", "bt" gives me this as the ENTIRE backtrace:
(gdb) bt
#0 0x000000000040fb40 in std::string::c_str ()
(gdb)
though, doing "tbreak +1" and "cont" and then "bt"
does once again get me a valid traceback.

The only way I can think of that this could happen: you have some active display which requires GDB to evaluate some expression every time it stops, and that expression can't be evaluated, yielding Invalid binary operation on numbers error.
Use info display to see current "auto display" expressions.

Related

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.

Is there a way to see which thread is printing to stdout or stderr with gdb?

I am debugging a multithreaded application with gdb.
I can see the threads, and play switch / break with them, but sometimes when I am attached to a particular thread, some of the other threads print something.
How can I find out which thread is printing what part?
Aside from setting breakpoints at strategic places [printf, fprintf, write, or some such], I suppose you could prefix (or postfix) any printf with a thread-id (but you would probably need to add that manually for every printf - or ones that you need to know about at least).
If you are using cout rather than printf, it may be a bit easier, as you could do (something as ugly as) something like this:
#define cout cout << pthread_self() << ":"
Although it may cause a few issues with things like cout.flush() or cout.setprecision().
First, you need to set conditional breakpoint on write system call with FD number in condition and stop at this breakpoint.
The exact condition depends on architecture you are using.
For 64-bit x86 it can be:
(gdb) catch syscall write
(gdb) condition 1 $rdi==1
For 32-bit:
(gdb) catch syscall write
(gdb) condition 1 $ebx==1
These examples are for stdout. For stderr, condition will change slightly, for example (gdb) condition 1 $rdi==2.
After that done you can easily see thread number either from info threads output or manually call pthread_self() like this:
(gdb) p pthread_self()

How to print result of C++ evaluation with GDB?

I've been looking around but was unable to figure out how one could print out in GDB the result of an evaluation. For example, in the code below:
if (strcmp(current_node->word,min_node->word) > 0)
min_node = current_node;
(above I was trying out a possible method for checking alphabetical order for strings, and wasn't absolutely certain it works correctly.)
Now I could watch min_node and see if the value changes but in more involved code this is sometimes more complicated. I am wondering if there is a simple way to watch the evaluation of a test on the line where GDB / program flow currently is.
There is no expression-level single stepping in gdb, if that's what you are asking for.
Your options are (from most commonly to most infrequently used):
evaluate the expression in gdb, doing print strcmp(current_node->word,min_node->word). Surprisingly, this works: gdb can evaluate function calls, by injecting code into the running program and having it execute the code. Of course, this is fairly dangerous if the functions have side effects or may crash; in this case, it is so harmless that people typically won't think about potential problems.
perform instruction-level (assembly) single-stepping (ni/si). When the call instruction is done, you find the result in a register, according to the processor conventions (%eax on x86).
edit the code to assign intermediate values to variables, and split that into separate lines/statements; then use regular single-stepping and inspect the variables.
you may simply try to type in :
call "my_funtion()"
as far as i rember, though it won't work when a function is inlined.