如何在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::set
和std::map
的printers.py文件。 由于_Rep_type
types在两者中都是私有的。 特别是,我从svn回购中的gcc-4_6分支版本中将std::map
和std::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程序可能会被gdb
debugging,反之亦然。 但为了避免上面发布的问题,如果你使用了clang
,你应该使用lldb
,如果你使用g++
话应该使用gdb
。
- “新运营商”和“运营商新”之间的区别?
- 并行vs omp simd:什么时候使用每个?
- 在调用condition_variable.notify_one()之前是否必须获取locking?
- 为什么我不能这样做:dynamic x = new ExpandoObject {Foo = 12,Bar =“twelve”}
- 如何获取C#正则expression式中的捕获组的名称?
- 在kernel.h的minmacros中,“(void)(&_min1 ==&_min2)”的function是什么?
- 如何从C中的控制台读取一行?
- 检查AVPlayer的播放状态
- 我怎样才能把一个整数转换成它的口头expression?