Симпатичные принтеры для карт выкидывают ошибку типа - PullRequest
6 голосов
/ 02 февраля 2012

Я настроил симпатичные принтеры, используя http://wiki.eclipse.org/CDT/User/FAQ#How_can_I_inspect_the_contents_of_STL_containers.3F. Он успешно работает для векторных и других контейнеров. Однако я не могу проверить карты, как в примере ниже:

#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;
}

Я получаю следующую ошибку при печати с использованием 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

Ответы [ 2 ]

18 голосов
/ 02 февраля 2012

Какой компилятор (и какую версию) вы использовали для создания своего тестового источника?

Я предполагаю, что это была не последняя версия g++.Вот что я получаю с 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}

Обновление:

Это то, что я получаю для версии: g ++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3

Я вижу проблему.Инструкции, на которые вы ссылались, являются неверными .

В частности, инструкции предлагают: svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python, но проблема в том, что код Python достигает libstdc++ внутренних элементов , и, следовательно, должен соответствовать этим внутренним элементам (по этой причине симпатичные принтеры являются частью GCC, а не частью GDB, на что пожаловался bruce.banner).

Когда высделал свежий svn co ..., вы взяли копию кода Python, который больше не соответствует вашим libstdc++ внутренним компонентам, и это то, что вызывает у вас проблемы.

В частности, svn log показывает, что find_type было добавлено здесь:

r183732 | tromey | 2012-01-30 08:25:11 -0800 (Mon, 30 Jan 2012) | 27 lines

Это на намного позже, чем gcc-4.4.3.Тогда вы хотите получить симпатичные принтеры, которые соответствуют вашей версии libstdc++, например:

svn co svn://gcc.gnu.org/svn/gcc/branches/gcc_4_4_3_release/libstdc++-v3/python

За исключением приведенного выше, команда работать не будет, поскольку gcc 4.4.3 предшествует симпатичным принтерам.

Независимо от того, реализация std::map (и большая часть остальных внутренних компонентов STL) не изменилась между 4.4.3 и 4.6, и эта команда делает работа:

 svn co svn://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc++-v3/python
0 голосов
/ 02 февраля 2012

В моей системе тип _Rep_type не является общедоступным типом std::map (это закрытый тип определения), поэтому скрипт пытается определить тип переменной <yourmap>._M_t, которая имеет тип _Rep_type ...

Я пытался:

typedef std::map<int,int> map_t;
map_t m;
m.insert(map_t::value_type(3,4));

, затем в gdb я могу напечатать ключ 3 следующим образом (следуя функции печати из скрипта, который я связал ниже):

p *(int*)(void*)(m._M_t._M_impl._M_header._M_left+1)

Где _M_t в std::map имеет тип _Rb_tree, но этот тип не является общедоступным на карте (вы можете увидеть это в заголовке map, в частности, заголовке <path/to/std-headers/dir/bits/stl_map.hфайл.

Не уверен, что это поможет, но в основном возникает проблема с загружаемой функцией довольно печати Python.

Я только чтопопытался добавить к .gdbinit материал из GNU GDB Командная таблица отладчика с yolinux.com (я гуглил для gdb pretty print) и с этим я получаю разумный вывод:

(gdb) pmap m int int
elem[0].left: $3 = 3
elem[0].right: $4 = 4
...