问题
I've configured pretty printers using http://wiki.eclipse.org/CDT/User/FAQ#How_can_I_inspect_the_contents_of_STL_containers.3F. It successfully works for vector and other containers. However I can't get to inspect maps as in the example below:
#include <map>
#include <iostream>
using namespace std;
int main ()
{
map <int, string> mapIntToString;
map <int, int> mapInt2;
mapIntToString.insert (map <int, string>::value_type (3, "Three"));
mapInt2.insert (map <int, int>::value_type (3, 4));
return 0;
}
I get the following error when printing using gdb:
(gdb) p mapInt2
$1 = std::map with 1 elementsTraceback (most recent call last):
File "/home/myuser/opt/gdb_printers/python/libstdcxx/v6/printers.py", line 422, in children
rep_type = find_type(self.val.type, '_Rep_type')
File "/home/myuser/opt/gdb_printers/python/libstdcxx/v6/printers.py", line 45, in find_type
raise ValueError, "Cannot find type %s::%s" % (str(orig), name)
ValueError: Cannot find type std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::_Rep_type
回答1:
What compiler (and which version) did you use to build your test source?
I am guessing it wasn't a recent version of g++
. Here is what I get with g++ 4.4.3-4ubuntu5
:
$ gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) b 12
Breakpoint 1 at 0x400de3: file t.cc, line 12.
(gdb) r
Breakpoint 1, main () at t.cc:12
12 return 0;
(gdb) p mapInt2
$1 = std::map with 1 elements = {[3] = 4}
Update:
This is what I get for the version: g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
I see the problem. The instructions you've referenced are incorrect.
In particular, the instructions suggest: svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python
, but the problem is that the python code reaches into libstdc++
internals, and therefore must match these internals (this is the reason the pretty printers are part of GCC and not part of GDB, a fact bruce.banner complained about).
When you did a fresh svn co ...
, you picked up a copy of python code that no longer matches your libstdc++
internals, and that's what is causing you problems.
In particular, svn log
shows that find_type
was added here:
r183732 | tromey | 2012-01-30 08:25:11 -0800 (Mon, 30 Jan 2012) | 27 lines
That's much later than gcc-4.4.3
. What you want to do then, is to get pretty printers that match your version of libstdc++
, like so:
svn co svn://gcc.gnu.org/svn/gcc/branches/gcc_4_4_3_release/libstdc++-v3/python
Except above command will not work, because gcc 4.4.3 predates the pretty printers.
No matter, the implementation of std::map
(and much of the rest of STL internals) has not changed between 4.4.3 and 4.6, and this command does work:
svn co svn://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc++-v3/python
回答2:
On my system the type _Rep_type
is not public type of std::map
(it's private typedef) so the script is trying to figure out a type of <yourmap>._M_t
variable which is of type _Rep_type
...
I tried:
typedef std::map<int,int> map_t;
map_t m;
m.insert(map_t::value_type(3,4));
then in gdb
I can print the key 3
like this (following the print function from the script I linked below):
p *(int*)(void*)(m._M_t._M_impl._M_header._M_left+1)
Where the _M_t
in std::map
is of _Rb_tree
type but the type is not public in map (you can see that in your map
header, specifically <path/to/std-headers/dir/bits/stl_map.h
header file.
Not sure if that helps one bit, basically there seems to be an issue with the pretty print python function that you are loading.
I've just tried adding to .gdbinit
stuff from GNU GDB Debugger Command Cheat Sheet from yolinux.com (I googled for gdb pretty print
) and with that I get reasonable output:
(gdb) pmap m int int
elem[0].left: $3 = 3
elem[0].right: $4 = 4
来源:https://stackoverflow.com/questions/9102967/pretty-printers-for-maps-throwing-a-type-error