如何在GDB中打印STL容器?

时间:2012-07-23 03:16:36

标签: c++ linux debugging stl gdb

我已按照说明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。

9 个答案:

答案 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_typechildren中的例程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添加了几个命令(pvectorplistpmap等),其功能是打印STL的元素。它还添加了print pretty,生成的格式如下:

enter image description here

此外,如果您想知道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++