C++ 如何在GDB中漂亮地打印STL容器?
我按照说明安装了PythonPretty打印机以查看STL容器。我的C++ 如何在GDB中漂亮地打印STL容器?,c++,linux,debugging,stl,gdb,C++,Linux,Debugging,Stl,Gdb,我按照说明安装了PythonPretty打印机以查看STL容器。我的~/.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并尝试打印STL类型
~/.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并尝试打印STL类型时,会得到以下结果:
print myString
Python Exception <class 'gdb.error'> No type named std::basic_string<char>::_Rep.:
$3 =
打印myString
Python异常没有名为std::basic_string::_Rep.:的类型
$3 =
有人能解释一下吗?我运行的是GDB7.4附带的Ubuntu 12.04。我认为您使用的是非GNU STL库,或者可能是非常旧的GCC
libstdc++
。在我的编译器上,普通STL字符串的类型是:std::basic_string
。请注意,这不是std::basic_字符串
Python代码中包含以下内容:
reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
这将查找一个嵌套类型
::Rep
,不管基字符串类型实际上是什么。错误消息指示您正在使用的任何奇怪库的字符串类实际上没有嵌套类型。您可以尝试使用下面的GDB宏(将其附加到~/.gdbinit文件)要打印STL容器类型数据甚至其数据成员:如果在Python异常后键入info-type\u-Rep
,gdb将通知您加载的与之匹配的类。该列表可以帮助您找到Python找不到std::string类的原因
我刚刚遇到了你的问题,在我的例子中是英特尔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;
为此:
reptype = gdb.lookup_type (str (realtype) + '::' + str (realtype) + '::_Rep').pointer ()
使用从info type
获得的列表,您可以修复漂亮的打印机,使其正常工作。检查您的gcc版本。如果小于4.7,则需要使用另一个printer.py文件。从中获取文件。我处理了这个问题,并在尝试解决问题时点击了此页面。我最终修复了它,我认为分享我的经验是值得的
我使用的是gcc-5.2,所以我从svn repo下载了gcc-5-branch版本的pretty printer。然而,我不得不做这两个MOD:
编辑~/.gdbinit
文件时,建议添加
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\u libstdcxx\u printers(None)
进行注释,因为我不断收到一个错误,告诉我libstdcxx\u打印机已经注册。显然,他们在导入阶段注册
我必须为std::set
和std::map
编辑printers.py文件。因为类型\u Rep\u type
在这两种类型中都是私有的。特别是,我将std::map
和std::set
中的例程children
替换为svn repo上gcc-4_6-branch版本的pretty printer中相应的例程。从那以后就没有出错,现在打印出来的东西很好
希望这能有所帮助。它只适用于Ubuntu 17.04
Debian现在似乎终于正确地集成了一些东西:
main.cpp
#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));
}
结果:
(gdb) p v
$1 = std::vector of length 3, capacity 4 = {0, 1, 2}
(gdb) p m
$2 = std::map with 3 elements = {[0] = 0, [1] = -1, [2] = -2}
我们可以看到,pretty打印机安装有:
(gdb) 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++库包<代码> LBSTDC++6 组成的,位于GCCC源代码<> LBSTDC++-V3/Python /LIbSTDCXXX <代码>:
TODO:GDB如何找到该文件是最后一个疑问,它不在我的Python路径中:Python-c“import sys;print('\n.join(sys.path))”
所以它必须在某个地方硬编码
自定义类
请参见如何定义自定义toString
方法并在以下位置调用它:
检查优化代码中的特定元素
上次我检查的时候很难,你会得到“无法计算函数-可能在直线上”
对于未优化的代码,它是有效的:当程序是LLVM构建(由clang
编译)时,通常会出现上面所述的错误,并且您尝试通过gdb
对其进行调试(应该用于GCC构建程序)。
理论上,LLVM构建程序可以由gdb
调试,反之亦然。但是
为避免上述问题,如果使用clang
,则应使用lldb
;如果使用g++
,而不是中列出的方法,则应使用gdb
,您可以尝试该脚本
按以下步骤进行:
1) 将脚本下载到/your/path
。将其命名为某个名称,例如your_Name.conf
2) 如果没有主目录,请将~/.gdbinit
文件添加到主目录
3) 在~/.gdbinit
中添加一行source/your/path/your_name.conf
4) 重新启动gdb。尝试pvector
您可以使用help pvector
等命令查找帮助信息
e、 g
仅供参考,将几个命令(pvector
,plist
,pmap
等)添加到gdb,其功能是打印STL的元素。它还添加了print pretty
,产生如下格式:
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中如何准确地访问STL元素,只需阅读命令的代码即可。密码里没有秘密^_^
e、 g。
向量通过\u M\u impl.\u M\u start
p vec.\u M\u impl.\u M\u start+4打印vec[4]
类似于
在~/.gdbinit为我工作:
python
import sys
sys.path.insert(0, '/usr/share/gcc-8/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end
它可以简单地说是C++库改变了它的内部类型和成员变量,而Python模块没有跟上。你能粘贴更多的信息,比如C++源代码、编译器选项等等吗?我刚刚在Ubuntu12.04上测试了这个,它对我很有效。在CEntOS 7上对我很有效。当您启动gdb时,要查看的一个潜在错误是正确的。它可能会打印一个python错误,您可能会错过它。@Evg我还没有进一步研究它。这对我来说很有效,只是我不知道到底是怎么回事。如果你知道细节,请告诉我。这对我来说很有用-
/usr/share/gcc-7/python/libstdcxx/v6/printers.py
pvector vec 5 # Prints element[5] in vec
pvector vec 5 10 # Prints elements in range [5, 10] in vec. (5, 6, 7, 8, 9, 10)
python
import sys
sys.path.insert(0, '/usr/share/gcc-8/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end