How to view the internal data of a smart pointer inside gdb? - c++

I've got test program like below:
#include<memory>
#include<iostream>
using namespace std;
int main()
{
shared_ptr<int> si(new int(5));
return 0;
}
Debug it:
(gdb) l
1 #include<memory>
2 #include<iostream>
3 using namespace std;
4
5 int main()
6 {
7 shared_ptr<int> si(new int(5));
8 return 0;
9 }
10
(gdb) b 8
Breakpoint 1 at 0x400bba: file testshare.cpp, line 8.
(gdb) r
Starting program: /home/x/cpp/x01/a.out
Breakpoint 1, main () at testshare.cpp:8
8 return 0;
(gdb) p si
$1 = std::shared_ptr (count 1, weak 0) 0x614c20
It only prints out the pointer type information of si, but how to get the value stored in it (in this case 5)?
How can I check the internal content of si during debugging?

Try the following:
p *si._M_ptr
Now, this assumes that you're using libstdc++.so, given the output for p si.
Alternatively, you could use the value 0x614c20 directly (from your output):
p {int}0x614c20
Both should display the value 5.

but how to get the value stored in it
You will have to cast raw pointer to actual pointer type stored in std::shared_ptr. Use whatis to know what the actual pointer type is.
(gdb) p si
$8 = std::shared_ptr (count 1, weak 0) 0x614c20
(gdb) whatis si
type = std::shared_ptr<int>
(gdb) p *(int*)0x614c20
$9 = 5

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?

pointer to a variable is not updating variable when dereferenced

This is a debugging problem I've been trying to solve. I know the bit mask I need to apply to make b equal a. I inspected with gdb to find the difference between a and b. The variables b and a are char[] types and set prior to reaching the 'bug'.
#include <string.h>
int main() {
char a[1] = "a";
char b[1] = "b";
int *x;
x = (int *) b;
// bug in next line
*x = *x & 0xffffffff;
return memcmp(a, b, 1);
}
Until a equals b, I can't solve the problem. The only constraint given is that the bug is in the line noted, no other code is to be changed. There is no rule saying I can't add lines after the bug, though and before the memcmp().The issue I find is that nothing I do to the bit mask changes the value of b, ever. I've set breakpoints and inspected the value of x and *x before and after the bug, but x seems to not change.
Breakpoint 1, main () at test.c:9
9 *x = *x & 0xffffffff;
(gdb) print (int) a
$1 = -6922
(gdb) print (int) b
$2 = -6921
(gdb) print (int) x
$3 = -6921
(gdb) step
Breakpoint 2, main () at test.c:10
10 return memcmp(a, b, 1);
(gdb) print (int) a
$4 = -6922
(gdb) print (int) b
$5 = -6921
(gdb) print (int) x
$6 = -6921
I don't see how this can be solved the way requested, by modifying the constant in the line where the bug is. Any help to understand how to use x to update b using a bitwise mask would be appreciated.
x is a pointer; casting it to an int simply gives you the address as a decimal number.
a and b are both arrays, which will decay to a pointer when you do operations that require a pointer. By casting them to int you're again getting the address of the variable. The address doesn't change with the operation you're performing, even when the contents at that address changes.
Since a and b are both smaller than an int, your code is likely to mess up in ways that are extremely painful. Even if they were the right size, this isn't guaranteed to do the right thing.
You are trying to change the address of b but in
*x = *x & 0xffffffff;
You are changing the value because you are dereferencing x. Yyou need to apply the manipulation to x itself like
x = x & 0xffffffff;
And then you need to reassign x into b.
This will run afoul of the strict aliasing rules.

Array of pointer not giving proper output as it suppose?

Hi i have array of two pointers int *p[2] and i am trying to store 3 address of integer lets take &i,&j,&k as below code At *p[0]
i am getting garbage why here garbage ?it should be at p[2]? At *p[1] i am getting value it is ok but At *p[2] i am getting value here i should get garbage?
#include<stdio.h>
int main()
{
int i=10,j=20,k=30;
int *p[2]; // here p is array of 2 pointers
p[0]=&i; // but here i am storing
p[1]=&j; // 3 address of variable i,j,k
p[2]=&k;
printf("p[0]=%d\n",*p[0]); // why garbage here ?
printf("p[1]=%d\n",*p[1]); // here 20
printf("p[2]=%d\n",*p[2]); // here 30 why here ?
}
printf("p[2]=%d\n",*p[2]); // here 30 why here ?
Because p has two elements, not three. You can access elements 0 and 1, but accessing 2 is undefined behavior. Any number can be printed, or your program could crash when you invoke undefined behavior.
I am getting value here i should get garbage?
30 is as good a garbage value as any other number.
**EDIT (in response to an edit of the question) When you assign p[2] = &k you write to a location that is not allocated to your program. However, if the write operation completes without a crash, the new value would stay in memory.
Since the memory to which you wrote an address of k does not belong to your program, the system may write a new value into it. However, it wouldn't do it with 100% certainty: it may not write a new value into that memory at all. This is precisely what appears to be happening in your case: the value of &k written into p[2] illegally "survives" past two invocations of printf, producing 30 as the result.
u are using int *p[2], which is an array of size 2. only p[0] and p[1] are valid. remember the index of an array in c++ starts with 0 not 1. using p[2] would end up with something strange.
you are having array of two pointers int *p[2]. But you are trying to print the next element using pointer-
printf("p[2]=%d\n",*p[2]);
It results in undefined behavior. Anything can happen. But you are getting 30 some times you may get garbage values.
For your program i am getting-
root#ubuntu:~/c/array/string# ./a.out
p[0]=10
p[1]=20
p[2]=-13543595 // note this value. Undefined Behaviour
root#ubuntu:~/c/array/string#
first of all you need
int *p[3].
secondly since you used
int *p[2]
p[2] wasn't kept aside for this array. so what was there at p[2]? in my case it was variable k.
mine was 64 bit system with 64 bit pointers.
my output
p[0]=10
p[1]=20
p[2]=32767
and look at the gdb dump especially the addresses of k and p[2]
(gdb) p p[0]
$7 = (int *) 0x7fffffffe02c
(gdb) p p[1]
$8 = (int *) 0x7fffffffe028
(gdb) p p[2]
$9 = (int *) 0x7fffffffe024
(gdb) p &i
$10 = (int *) 0x7fffffffe02c
(gdb) p &j
$11 = (int *) 0x7fffffffe028
(gdb) p &k
$12 = (int *) 0x7fffffffe024
(gdb) p &p
$14 = (int *(*)[2]) 0x7fffffffe010
(gdb) x/32 0x7fffffffe010
0x7fffffffe010: -8148 32767 -8152 32767
0x7fffffffe020: -8156 32767 20 10
in your case it must have been the address of i.

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.