Pretty printers for maps throwing a type error
Asked Answered
H

2

6

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
Haughty answered 1/2, 2012 at 20:37 Comment(1)
I came as far as finding out that _Rep_type is [at least on some systems] a private typedef in std::map. perhap's that assumption is not always true. I suggest you notify the developers of pretty printers.Enantiomorph
H
18

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
Herne answered 2/2, 2012 at 7:10 Comment(3)
When I build gdb 7.3 from source on Ubuntu 7.3 it cannot print stl elements by default, I have to install the pretty printers. Do you not feel this is a step backwards?Jacquijacquie
This is what I get for the version: g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3Haughty
Thank you employed russian! I had this problem at my work. We are using gcc/g++ that comes out of the box with RHEL5 and I was having difficulty following the instructions on setting up PrettyPrinters and I was getting the same std::map problem before your help!Rosina
S
0

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
Spindly answered 1/2, 2012 at 22:57 Comment(2)
The fact that _Rep_type is a private typedef is irrelevant: GDB knows all types (and typedefs) when debug info is available. And the pmap is a really old and clunky way to print STL. Python pretty-printers are much nicer (when they work ;-)Herne
Well, it seems to me that for some reason my GDB doesn't 'know' these types. I would prefer to stick with python pretty printers but don't know how to fix this problem. _Rep_type is private in stl_map.h, in my case.Haughty

© 2022 - 2024 — McMap. All rights reserved.