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

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.

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?

Local Variables in Dtrace

How do I access variables local to a function using dtrace?
For example, in the following snippet I would like to know the value of variable x using dtrace.
void foo(int a){
int x=some_fun(a);
}
Tracing local variables is impossible for kernel code because there is no mechanism to instrument arbitrary kernel instructions. Even in user-land, tracing local variables is somewhat convoluted and so, for the specific example you give, it would make a lot more sense to trace the return value of some_fun() instead.
If you must trace an arbitrary local variable then you will need to determine its location (typically a register or a location in memory) at the specific point of interest. For simple cases you may be able to do this by disassembling the function and inspecting the output. For more complex cases it may be helpful to build the object with DWARF and then find the DW_AT_location attribute of the local variable's DIE.
One you find the variable's location you'll need to express it in D; note that registers are exposed through the uregs[] array. Furthermore, you'll need to describe your probe using the offset within the function since dtrace(1) has no way of understanding line numbers. See the section on "User Process Tracing" in the Oracle Solaris Dynamic
Tracing Guide for more.
As an example, I wrote a trivial program containing
int
foo(int i)
{
int x;
...
for (x = 0; x < 10; x++)
i += 2;
and built it, as an amd64 executable, with DWARF...
cc -m64 -g -o demo demo.c
...before looking for foo() and its definition of x in the output
of dwarfdump demo:
< 1><0x000000e4> DW_TAG_subprogram
DW_AT_name "foo"
...
DW_AT_frame_base DW_OP_reg6
< 2><0x00000121> DW_TAG_variable
DW_AT_name "x"
...
DW_AT_location DW_OP_fbreg -24
x is described as DW_OP_fbreg -24 but DW_OP_fbreg itself must be
substituted by the result of the parent function's DW_AT_frame_base
attribute, i.e. DW_OP_reg6. DWARF uses its own architecture-agnostic
numbering for registers and the mapping to individual registers is up to
the appropriate standards body. In this case, the AMD64 ABI tells
us that DWARF register 6 corresponds to %rbp. Thus x is stored at
%rbp - 0x18. (For more about DWARF itself I recommend Michael Eager's
Introduction to the DWARF Debugging Format.)
Thus, if you had found that the line of source in which you're
interested is at offset 0x32 (perhaps by inspecting the DWARF
line table) then you might write a probe like:
pid$target:a.out:foo:32
{
self->up = (uintptr_t)(uregs[R_RBP] - 0x18);
self->kp = (int *)copyin(self->up, sizeof (int));
printf("x = %d\n", *self->kp);
self->up = 0;
self->kp = 0;
}
This is what I see when I run the demo program:
# dtrace -q -s test.d -c /tmp/demo
x = 1
x = 2
x = 3
x = 4
x = 5
x = 6
x = 7
x = 8
x = 9
x = 10
#

gdb cannot index into an array and print value

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.

Watch mathematical C++ expression in Eclipse Debugger [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why does gdb evaluate sqrt(3) to 0?
C newbie here. There must be an obvious explanation why gdb gives strange outputs when trying to use math.h functions in-line. For example, the fabs function below is supposed to take the absolute value, and return a double.
(gdb) p cos(2*3.141/4)
$13 = 1073291460
(gdb) p fabs(-3)
$14 = 0
(gdb) p fabs(3)
$15 = 0
(gdb) p fabs(3.333)
$16 = 1
(gdb) p (double) fabs(-3.234)
$17 = 1
(gdb) p (double) fabs((double)-3.234)
$18 = 1
(gdb) p ((double(*)(double))fabs)(-3)
$19 = 682945
The code I'm using has included math.h, and the actual code appears to execute correctly, although the same code placed in-line in gdb produces strange results. I could ignore it, but it seems a good learning opportunity.
(Ref: http://lists.gnu.org/archive/html/gdb/2009-12/msg00004.html)
gdb is missing the debug information of the cos function, and therefore assume it is an int cos(...) function, so the values are not returned correctly (esp. on x86 as the registers to store floating point return and integer return are different).
This could be worked around by specifying the type:
(gdb) p ((double(*)(double))cos) (1.0)
$18 = 0.54030230586813977

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.