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

我已经按照GDB Wiki上的说明安装了用于查看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并尝试打印STL类型时,得到以下信息:

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

谁能对此有所启发? 我正在运行GDB 7.4随附的Ubuntu 12.04。

Nick Hutchinson asked 2020-02-29T10:31:06Z
8个解决方案
10 votes

您可以尝试使用下面的GDB宏(将其添加到〜/ .gdbinit文件中)来打印STL容器类型数据,甚至是其数据成员:[https://gist.github.com/3978082]

Fei answered 2020-02-29T10:31:16Z
6 votes

它仅适用于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));
}

编译:

g++ -O0 -ggdb3 -o main.out -std=c++98 main.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 ++库软件包toString,位于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]

待办事项:GDB如何找到该文件是最后的麻烦,它不在我的Python路径中:toString,因此必须在某处进行硬编码?

自订课程

请参阅如何定义自定义toString方法并在以下位置调用该方法:使用GDB打印C ++类对象

4 votes

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

Bingfeng answered 2020-02-29T10:32:57Z
3 votes

除了您提到的链接中列出的方法外,您还可以在此处尝试使用脚本,

进行如下操作:

1)将脚本下载到p vec._M_impl._M_start + 4 # prints vec[4],并以其他名称命名,例如 plist

2)如果您没有,请在主目录中添加一个p vec._M_impl._M_start + 4 # prints vec[4]文件。

3)在您的plist中添加一行p vec._M_impl._M_start + 4 # prints vec[4]

4)重新启动gdb。 尝试p vec._M_impl._M_start + 4 # prints vec[4]

您可以使用p vec._M_impl._M_start + 4 # prints vec[4]之类的命令找到帮助信息。

岁月

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)

仅供参考,该脚本向gdb添加了一些命令(p vec._M_impl._M_start + 4 # prints vec[4]plistpmap等),其功能是打印STL的元素。 它还添加了print pretty,产生的格式如下:

enter image description here

另外,如果您想知道如何在gdb中精确地访问STL元素,只需阅读命令代码即可。 代码中没有秘密。 ^ _ ^

例如向量可通过p vec._M_impl._M_start + 4 # prints vec[4]访问

p vec._M_impl._M_start + 4 # prints vec[4]

Scott Yang answered 2020-02-29T10:34:06Z
2 votes

如果在Python异常后键入info type,则gdb将通知您有关已加载的与_Rep匹配的类。 该列表可以帮助您找到python为什么找不到您的std::string class的原因。

我只是遇到了您的问题,在我的情况下是intel c编译器icc,它破坏了漂亮的打印效果。 特别地,info type的不合格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中的类info type,将字符串的非限定名称添加到要在gdb中查找的typename中。 替换行:

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

有了这个:

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

使用从info type获得的列表,您可以修复漂亮的打印机以使其工作。

Manuel Núñez answered 2020-02-29T10:34:51Z
2 votes

我遇到了这个问题,并试图找出该页面时点击了该页面。 我最终修复了它,我认为值得分享我的经验。

我正在使用gcc-5.2,因此我从svn存储库下载了漂亮打印机的gcc-5分支版本。 但是,我必须执行以下两个mod:

1)在编辑.gitinit文件时,建议添加

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

但是,我不得不注释行std::set,因为我不断收到一个错误消息,告诉我libstdcxx_printers已被注册。 显然,它们在导入阶段已注册。

2)我必须编辑std::setstd::map的printers.py文件。因为_Rep_type类型在这两种类型中都是私有的。 特别是,我用svn repo上gcc-4_6-branch版本的pretty打印机版本中的相应打印机替换了std::mapstd::set中的例程children。 从那以后没有任何错误,现在东西可以很好地打印出来。

希望这可以帮助。

bartgol answered 2020-02-29T10:35:43Z
1 votes

我认为您使用的是非GNU STL库,或者可能使用的是非常老的GCC::Rep。我的编译器上常规STL字符串的类型为:::Rep。请注意,这不是std::basic_string<char>

Python代码包含以下内容:

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

该查询查找嵌套类型为::Rep的任何基本字符串类型实际上是什么。 该错误消息表示您正在使用的任何奇怪库的字符串类实际上都没有::Rep嵌套类型。

Omnifarious answered 2020-02-29T10:36:14Z
0 votes

当程序是LLVM-build(由clang编译)时,通常会出现类似上述错误,并且尝试通过gdb(应用于GCC-build程序)对其进行调试。从理论上讲,LLVM生成程序可以通过gdb进行调试,反之亦然。 但为避免上述问题,如果使用clang,则应使用lldb,如果使用g++,则应使用gdb

Ans answered 2020-02-29T10:36:34Z
translate from https://stackoverflow.com:/questions/11606048/how-to-pretty-print-stl-containers-in-gdb