gdb cannot index into an array and print value - c++

I have an object a of type vector<char>. I know it is 10 elements long. But, when I do p a[5] in gdb, I get an error saying gdb could not resolve symbol operator[].
void foo()
{
vector<char> a (10, 10); // put a breakpoint here.
}
Could you please suggest me a way to print the value at index in gdb? Right now, I did something really lame -
char c1=a[1]; char c2 = a[2]; char c3 = a[3]; // ... so on and forth
Can I trust the values in c1, c2, etc
P.S. I have built my code with DEBUG symbols.

A vector is not the same as an array or a pointer. A vector typically has a pointer to the start, which you can use to access elements. Try something like this
p *(a._M_impl._M_start+5)
Here I'm accessing the pointer to the start of the array, adding 5 to get the element at index 5.

This works without issues with gdb 7.11.1
(gdb) b main
Breakpoint 1 at 0x400bd3: file t.C, line 6.
(gdb) run
Starting program: /tmp/t
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.23.1-8.fc24.x86_64
Breakpoint 1, main () at t.C:6
6 std::vector<char> a={'a','b','c','d','e','f'};
Missing separate debuginfos, use: dnf debuginfo-install libgcc-6.1.1-3.fc24.x86_64 libstdc++-6.1.1-3.fc24.x86_64
(gdb) n
8 std::cout << "Ok" << std::endl;
(gdb) p a
$1 = std::vector of length 6, capacity 6 = {97 'a', 98 'b', 99 'c', 100 'd',
101 'e', 102 'f'}
(gdb) p a[2]
$2 = 99 'c'
The answer here is to update to the current version of gcc and gdb.

Related

struct field name conflict with stl array in GDB

#include <array>
typedef struct {
int array;
} tp1;
int main()
{
std::array<int,8> array1;
/*int array=0;*/
/*array ++;*/
tp1 v1;
v1.array = 2;
return 0;
}
When struct has field "array" and the code uses std::array, it seems the 2 "array" are conflicted in gdb. I get syntax error in printing v1.array:
Temporary breakpoint 1, main () at a2.c:12
12 v1.array = 2;
(gdb) n
13 return 0;
(gdb) p v1.array
A syntax error in expression, near `'.
But if I add a local variable "array", it then works fine.
(gdb) p array
$1 = 1
(gdb) p v1.array
$2 = 2
std::array should be in namespace std, and not related to field name. Not sure why it gets confused.
Any suggestion to print v1.array without the local variable?
Not sure why it gets confused.
This is (was?) surely a bug in GDB.
It does not reproduce when using GDB 10.0 on x86_64, while compiling with g++ (Debian 9.3.0-8):
Temporary breakpoint 1, main () at t.cc:12
12 v1.array = 2;
(gdb) n
13 return 0;
(gdb) p v1.array
$1 = 2
Try newer GDB version?

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.

Why can't gdb evaulate functions when !=/== and &&/|| are combined in an expression?

It may be that the difficulty I'm having in describing my problem is the reason I can't find anyone else with an instance of it. I am using gdb 7.4-2012.04.
It seems at the least that any expression involving both !=/== and &&/|| for vectors or vector iterators will fail to evaluate in gdb with the following error:
Cannot access memory at address 0x0
Here's a test case, followed by my compilation line and tests:
#include <stdio.h>
#include <iostream>
#include <stdint.h>
#include <vector>
using namespace std;
typedef char GUID[32];
int main(int argc, char **argv){
vector<int> vec;
for (int i=0; i<5; i++){
vec.push_back(i);
}
for (vector<int>::iterator vecIter=vec.begin(); vecIter!=vec.end(); vecIter++){
int i=0;//Just need a line gdb will recognize for a breakpoint.
}
cout << vec[0] << endl;//g++ needs to include operator[] in the binary for this to work.
return 0;
}
Here's a snippet of the tests I performed:
user#comp$ g++ -g -O0 any_test.cpp
user#comp$ gdb a.out
(gdb) b 16
(gdb) r
Breakpoint 1, main (argc=1, argv=0x7fffffffe288) at any_test.cpp:16
16 int i=0;//Just need a line gdb will recognize for a breakpoint.
(gdb) p *vecIter == vec[1] or *vecIter == vec[2]
Cannot access memory at address 0x0
The original useful statement does not work. Let's reduce a bit and find the problem.
(gdb) p vec[1] or *vecIter == vec[2]
Cannot access memory at address 0x0
(gdb) p vec[1] or *vecIter
$1 = true
(gdb) p 1 or *vecIter == vec[2]
Cannot access memory at address 0x0
Looks like the problem is '==' after 'or'. Is this the same with other operators?
(gdb) p 1 and *vecIter == vec[2]
Cannot access memory at address 0x0
(gdb) p 1 and *vecIter != vec[2]
Cannot access memory at address 0x0
That's a resounding yes. What if I pull out all the functions for gdb? Just let it dereference and compare ints?
(gdb) p 1 or *vecIter._M_current == vec._M_impl._M_start[1]
$2 = true
Ok, let's check some combinations of derefs and functions to make sure it's not just one of these types that causes the problem:
(gdb) p 1 or *vecIter._M_current == *vecIter
Cannot access memory at address 0x0
(gdb) p 1 or vec._M_impl._M_start[1] == vec[1]
Cannot access memory at address 0x0
As you can see, the problem is not specifically the vector or its iterator. Any operator (function) called on either one will trigger this issue if inserted after &&/||, and on either side of an ==/!=.
EDIT: forgot a question again. My question is this:
Why do I get "Cannot access memory at address 0x0" in the line "p *vecIter == vec[1] or *vecIter == vec[2]"?
The problem is in functions that return references. Here's a minimal example:
int& g() { static int i; return i; }
int main() {}
The same problem is exhibited (I'm using gdb 7.8.1):
(gdb) p 0 || +g()
Cannot access memory at address 0x0
A workaround is to convert the reference to a pointer and indirect it:
(gdb) p 0 || +*&g()
$1 = true
Filed a bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17904
The order of evaluating "*vecIter == vec[1]" is evaluating *vecIter first, if true then skip evaluating vec[1] and the whole statement is true; and if false then evaluate vec[1]. The root cause here is that vecIter pointing to NULL memory, which is inaccessible, that *vecIter could not even be evaluated. Therefore gdb print out the "memory access" error.
same reason for other print statements of same error

Is there a gdb especially for c++? [duplicate]

Supposing to have something like this:
#include <map>
int main(){
std::map<int,int> m;
m[1] = 2;
m[2] = 4;
return 0;
}
I would like to be able to inspect the contents of the map running the program from gdb.
If I try using the subscript operator I get:
(gdb) p m[1]
Attempt to take address of value not located in memory.
Using the find method does not yield better results:
(gdb) p m.find(1)
Cannot evaluate function -- may be inlined
Is there a way to accomplish this?
The existing answers to this question are very out of date. With a recent GCC and GDB it Just WorksTM thanks to the built-in Python support in GDB 7.x and the libstdc++ pretty printers that come with GCC.
For the OP's example I get:
(gdb) print m
$1 = std::map with 2 elements = {[1] = 2, [2] = 4}
If it doesn't work automatically for you see the first bullet point on the STL Support page of the GDB wiki.
You can write Python pretty printers for your own types too, see Pretty Printing in the GDB manual.
I think there isn't, at least not if your source is optimized etc. However, there are some macros for gdb that can inspect STL containers for you:
http://sourceware.org/ml/gdb/2008-02/msg00064.html
However, I don't use this, so YMMV
There's always the obvious: Define your own test-function... Call it from gdb. E.g.:
#define SHOW(X) cout << # X " = " << (X) << endl
void testPrint( map<int,int> & m, int i )
{
SHOW( m[i] );
SHOW( m.find(i)->first );
}
int
main()
{
std::map<int,int> m;
m[1] = 2;
m[2] = 4;
return 0; // Line 15.
}
And:
....
Breakpoint 1 at 0x400e08: file foo.C, line 15.
(gdb) run
Starting program: /tmp/z/qD
Breakpoint 1, main () at qD.C:15
(gdb) call testPrint( m, 2)
m[i] = 4
(*m.find(i)).first = 2
(gdb)
The stl-views.gdb used to be the best answer there was, but not anymore.
This isn't integrated into the mainline GDB yet, but here is what you get using the 'archer-tromey-python' branch:
(gdb) list
1 #include <map>
2 int main(){
3 std::map<int,int> m;
4 m[1] = 2;
5 m[2] = 4;
6 return 0;
7 }
(gdb) break 6
Breakpoint 1 at 0x8048274: file map.cc, line 6.
(gdb) run
Breakpoint 1, main () at map.cc:6
6 return 0;
(gdb) print m
$1 = std::map with 2 elements = {
[1] = 2,
[2] = 4
}
(gdb) quit
Try De-Referencing STL Containers: on this page: http://www.yolinux.com/TUTORIALS/GDB-Commands.html
The answers above are working and fine. In case you are using stl-views.gdb, here is the proper way of viewing the maps and elements inside it.
Let your map is as follows :
std::map<char, int> myMap;
(gdb) pmap myMap char int
i.e. pmap <variable_name> <left_element_type> <right_element_type> to see the elements in the map.
Hope that helps.
You can get around the second problem (Cannot evaluate function -- may be inlined) by making sure that your compiler uses DWARF-2 (or 3 or 4) debugging information when you compile your program. DWARF-2 includes inlining information, so you should be able to use either of the methods you described to access elements of your std::map container.
To compile with DWARF-2 debug info, add the -gdwarf-2 flag to your compile command.

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.