漂亮的地图打印机抛出类型错误

age*_*ada 6 c++ python gdb pretty-print

我使用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;
}
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

Emp*_*ian 18

您使用什么编译器(以及哪个版本)来构建测试源?

我猜它不是最新版本的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}
Run Code Online (Sandbox Code Playgroud)

更新:

这是我得到的版本: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 ...,你拿起了一个不再匹配你的libstdc++内部的python代码的副本,这就是导致你的问题.

特别是,这里添加的svn log节目find_type:

r183732 | tromey | 2012-01-30 08:25:11 -0800 (Mon, 30 Jan 2012) | 27 lines
Run Code Online (Sandbox Code Playgroud)

晚了gcc-4.4.3.你想要做的是获得与你的版本相匹配漂亮打印机libstdc++,如下所示:

svn co svn://gcc.gnu.org/svn/gcc/branches/gcc_4_4_3_release/libstdc++-v3/python
Run Code Online (Sandbox Code Playgroud)

除了上面的命令不起作用,因为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
Run Code Online (Sandbox Code Playgroud)


ste*_*anB 0

在我的系统上,类型_Rep_type不是公共类型std::map(它是私有 typedef),因此脚本试图找出类型<yourmap>._M_t变量的类型_Rep_type...的变量类型。

我试过:

typedef std::map<int,int> map_t;
map_t m;
m.insert(map_t::value_type(3,4));
Run Code Online (Sandbox Code Playgroud)

然后gdb我可以像这样打印密钥3(遵循下面链接的脚本中的打印功能):

p *(int*)(void*)(m._M_t._M_impl._M_header._M_left+1)
Run Code Online (Sandbox Code Playgroud)

其中_M_tinstd::map_Rb_tree类型,但该类型在 map 中不是公开的(您可以在map头文件中看到它,特别是<path/to/std-headers/dir/bits/stl_map.h头文件中)。

不确定这是否有一点帮助,基本上您正在加载的漂亮打印 python 函数似乎存在问题。

我刚刚尝试添加来自 yolinux.com 的 GNU GDB 调试器命令备忘单(我在 google 上搜索).gdbinit中的内容,并得到了合理的输出:gdb pretty print

(gdb) pmap m int int
elem[0].left: $3 = 3
elem[0].right: $4 = 4
Run Code Online (Sandbox Code Playgroud)

  • 事实上 `_Rep_type` 是私有 typedef 是无关紧要的:当调试信息可用时,GDB 知道*所有*类型(和 typedef)。而“pmap”是一种非常古老且笨拙的打印 STL 的方法。Python 漂亮的打印机*好多*好(当它们工作时;-) (3认同)