如何在GDB中漂亮地打印STL容器?

我按照GDB维基上的说明安装了用于查看STL容器的python漂亮打印机。 我的~/.gdbinit现在看起来像这样:

 python import sys sys.path.insert(0, '/opt/gdb_prettyprint/python') from libstdcxx.v6.printers import register_libstdcxx_printers register_libstdcxx_printers (None) end 

但是,当我运行GDB并尝试打印STLtypes时,我得到以下内容:

 print myString Python Exception <class 'gdb.error'> No type named std::basic_string<char>::_Rep.: $3 = 

任何人都可以点亮这个? 我运行的是GDB 7.4附带的Ubuntu 12.04。

您可以尝试使用下面的GDBmacros (附加到您的〜/ .gdbinit文件)来打印STL包含器types数据,甚至是它们的数据成员: https : //gist.github.com/3978082

检查你的gcc版本。 如果它小于4.7,则需要使用另一个printer.py文件。 从http://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc++-v3/python/获取该文件。;

如果在Pythonexception之后键入info type _Rep ,gdb会通知您加载的匹配_Rep的类。 该列表可以帮助您find为什么python无法find您的std::string class

我刚刚面对你的问题,在我的情况是英特尔C编译器,ICC,谁打破漂亮的打印。 特别是, std::string非限定icc名称导致:

 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep; 

但漂亮的打印机正在寻找不合格的海湾合作委员会名称:

 std::basic_string<char, std::char_traits<char>, std::allocator<char>::_Rep; 

我所做的解决我的问题是在printers.py中修改类StdStringPrinter ,将string的非限定名称添加到types名称以查找gdb。 更换线路:

 reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer () 

有了这个:

 reptype = gdb.lookup_type (str (realtype) + '::' + str (realtype) + '::_Rep').pointer () 

info type获得的列表,你可以修复你漂亮的打印机,使他们的工作。

我想你正在使用一个非GNU STL库,或者可能是一个非常古老的GCC libstdc++ 。 我的编译器上正常的STLstring的types是: std::basic_string<char, std::char_traits<char>, std::allocator<char> > 。 请注意,这不是std::basic_string<char>

Python代码中有这个:

 reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer () 

这个查找一个嵌套的types::Rep的任何基本stringtypes实际上是。 该错误消息指出,你正在使用的任何奇怪的库的string类实际上并没有::Rep嵌套types。

我跑了这个问题,并试图找出这个网页。 我最终修好了,我认为这是值得分享我的经验。

我使用的是gcc-5.2,所以我从svn repo下载了gcc-5分支的漂亮打印机版本。 不过,我不得不做这两个MODS:

1)编辑.gitinit文件时,build议添加的是

 python import sys sys.path.insert(0, '/home/bartgol/.gdb/gdb_printers/python') from libstdcxx.v6.printers import register_libstdcxx_printers register_libstdcxx_printers (None) end 

但是,我不得不注释register_libstdcxx_printers (None) ,因为我不断收到错误告诉我libstdcxx_printers已经注册。 显然他们在import阶段注册。

2)我必须编辑std::setstd::map的printers.py文件。 由于_Rep_typetypes在两者中都是私有的。 特别是,我从svn回购中的gcc-4_6分支版本中将std::mapstd::set的例程children代替为漂亮打印机版本中的相应子代。 从此没有错误,现在打印出来的东西很好。

希望这可以帮助。

它只适用于Ubuntu 17.04

Debian似乎现在已经正确地整合了一些东西:

 #include <map> #include <utility> #include <vector> int main() { std::vector<int> v; v.push_back(0); v.push_back(1); v.push_back(2); std::map<int,int> m; m.insert(std::make_pair(0, 0)); m.insert(std::make_pair(1, -1)); m.insert(std::make_pair(2, -2)); } 

编译:

 g++ -O0 -ggdb3 -o container.out -std=c++98 container.cpp 

结果:

 (gdb) pv $1 = std::vector of length 3, capacity 4 = {0, 1, 2} (gdb) pm $2 = std::map with 3 elements = {[0] = 0, [1] = -1, [2] = -2} 

我们可以看到漂亮的打印机安装了:

 info pretty-printer 

其中包含以下几行:

 global pretty-printers: objfile /usr/lib/x86_64-linux-gnu/libstdc++.so.6 pretty-printers: libstdc++-v6 std::map std::vector 

打印机由文件提供:

 /usr/share/gcc-7/python/libstdcxx/v6/printers.py 

它与主要的C ++库包libstdc++6 ,位于GCC源代码中的libstdc++-v3/python/libstdcxx : https : //github.com/gcc-mirror/gcc/blob/gcc-6_3_0-release /libstdc%2B%2B-v3/python/libstdcxx/v6/printers.py#L244

TODO:GDB是如何发现这个文件是最后一个mistery的,它不在我的Pythonpath中: python -c "import sys; print('\n'.join(sys.path))"所以它必须在某处硬编码?

像上面发布的错误通常在程序是LLVM-build(由clang编译)时出现,并且您尝试通过gdb (应该用于GCC-build程序)进行debugging。 理论上讲,LLVM-build程序可能会被gdbdebugging,反之亦然。 但为了避免上面发布的问题,如果你使用了clang ,你应该使用lldb ,如果你使用g++话应该使用gdb