我已按照说明on the GDB wiki安装python pretty-printers以查看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 =
有人可以对此有所了解吗?我正在运行Ubuntu 12.04,它带有GDB 7.4。
答案 0 :(得分:10)
您可以尝试使用以下 GDB宏(将其附加到〜/ .gdbinit 文件)来打印STL包含类型数据甚至是其数据成员:{{3 }}
答案 1 :(得分:4)
检查你的gcc版本。如果小于4.7,则需要使用另一个printer.py文件。从http://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc++-v3/python/获取文件。
答案 2 :(得分:2)
如果在Python异常后键入info type _Rep
,gdb将通知您与_Rep匹配的类。该列表可以帮助您找到python无法找到您的std::string class
。
我刚刚面对你的问题,在我的情况下是intel 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;
但漂亮的打印机正在寻找不合格的gcc名称:
std::basic_string<char, std::char_traits<char>, std::allocator<char>::_Rep;
我为解决我的问题所做的是修改printers.py中的类StdStringPrinter
,将字符串的非限定名称添加到要在gdb中查找的typename。替换线:
reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
用这个:
reptype = gdb.lookup_type (str (realtype) + '::' + str (realtype) + '::_Rep').pointer ()
使用info type
中获得的列表,您可以修复漂亮的打印机以使其正常工作。
答案 3 :(得分:2)
我遇到了这个问题并在尝试解决问题时点击此页面。我最终修复了它,我认为分享我的经验是值得的。
我正在使用gcc-5.2,所以我从svn repo下载了gcc-5-branch版本的漂亮打印机。但是,我必须做这两个mod:
1)编辑.gitinit文件时,建议添加
mongod -h | grep 'snmp-subagent'
但是,我必须对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
行进行评论,因为我一直收到错误,告诉我libstdcxx_printers已经注册了。显然他们在导入阶段就已注册。
2)我必须编辑register_libstdcxx_printers (None)
和std::set
的printers.py文件。由于类型std::map
在两者中都是私有的。特别是,我将_Rep_type
和children
中的例程std::map
替换为svn repo上gcc-4_6-branch版本中漂亮打印机版本中的相应版本。从那时起就没有任何错误,而且现在打印出来的东西很好。
希望这有帮助。
答案 4 :(得分:2)
它适用于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) 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}
我们可以看到漂亮的打印机安装时:
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如何发现该文件是最终的错误,它不在我的Python路径中:python -c "import sys; print('\n'.join(sys.path))"
所以它必须在某处硬编码?
答案 5 :(得分:1)
我认为您使用的是非GNU STL库,或者可能是非常古老的GCC libstdc++
。我的编译器上的普通STL字符串的类型是:std::basic_string<char, std::char_traits<char>, std::allocator<char> >
。请注意,这不是std::basic_string<char>
。
Python代码中有这个:
reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
这将查找嵌套类型::Rep
,无论基本字符串类型是什么。该错误消息表明您正在使用的任何奇怪库的字符串类实际上没有::Rep
嵌套类型。
答案 6 :(得分:1)
您可以尝试使用脚本the link you mentioned,
来代替here中列出的方法。执行以下操作:
1)将脚本下载到/your/path
。将其命名为其他名称,例如your_name.conf
。
2)如果没有~/.gdbinit
文件,请添加到主目录。
3)在您的source /your/path/your_name.conf
中添加一行~/.gdbinit
。
4)重新启动gdb。尝试pvector
您可以使用help pvector
之类的命令查找帮助信息。
例如
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)
FYI,the script向gdb添加了几个命令(pvector
,plist
,pmap
等),其功能是打印STL的元素。它还添加了print pretty
,生成的格式如下:
此外,如果您想知道gdb中STL元素的访问方式,请阅读命令代码。代码中没有秘密。 ^ _ ^
例如
向量由._M_impl._M_start
p vec._M_impl._M_start + 4 # prints vec[4]
答案 7 :(得分:1)
类似于enter link description here 在〜/ .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
答案 8 :(得分:0)
上面发布的错误通常在程序是LLVM-build(由clang
编译)时出现,并且您尝试通过gdb
调试它(应该用于GCC构建程序)。
理论上,LLVM构建程序可以由gdb
调试,反之亦然。但
为了避免上面发布的问题,如果您使用lldb
,则应使用clang
;如果您使用gdb
,则应使用g++
。