60

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

4

9 回答 9

14

它只适用于 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 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}

我们可以看到漂亮的打印机安装了:

(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++ 库包一起提供libstdc++6,位于libstdc++-v3/python/libstdcxxGCC 源代码中: https ://github.com/gcc-mirror/gcc/blob/releases/gcc-6.3.0/libstdc%2B%2B-v3/ python/libstdcxx/v6/printers.py#L244

TODO:GDB 如何发现该文件是最终的谜团,它不在我的 Python 路径中:python -c "import sys; print('\n'.join(sys.path))"所以它必须在某个地方进行硬编码?

自定义类

了解如何定义自定义toString方法并在以下位置调用它:使用 GDB 打印 C++ 类对象

检查优化代码中的特定元素

上次我检查时很难,你得到“无法评估函数——可能是内联的” C++、STL、GDB:无法评估函数可能是内联的

在未优化的代码上它可以工作:Inspecting standard container (std::map) contents with gdb

于 2017-09-24T10:52:36.150 回答
10

您可以尝试使用以下GDB 宏(将其附加到您的~/.gdbinit文件中)来打印 STL 容器类型数据甚至它们的数据成员:https ://gist.github.com/3978082

于 2012-10-30T03:10:05.660 回答
6

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

我正在使用 gcc-5.2,所以我从 svn repo 下载了漂亮打印机的 gcc-5-branch 版本。但是,我必须做这两个模组:

  1. 编辑~/.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_libstdcxx_printers (None),因为我不断收到错误消息,告诉我 libstdcxx_printers 已经注册。显然,他们在导入阶段进行了注册。

  1. 我必须为std::set和编辑 printers.py 文件std::map。由于类型_Rep_type在两者中都是私有的。特别是,我用svn repo 上的 gcc-4_6-branch 版本中的漂亮打印机版本中的相应children例程std::map替换了例程。std::set从那以后没有错误,现在打印出来的东西很好。

希望这可以帮助。

于 2015-10-19T20:29:41.760 回答
5

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

于 2013-07-11T13:42:19.293 回答
4

而不是你提到的链接中列出的方法,你可以试试这里的脚本,

执行以下操作:

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)

仅供参考,该脚本向 gdb添加了几个命令(pvectorplistpmap),其功能是打印 STL 的元素。它还添加了print pretty,产生了像这样的漂亮格式:

在此处输入图像描述

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

例如向量被访问._M_impl._M_start

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

于 2018-11-12T13:22:29.473 回答
2

如果您info type _Rep在 Python 异常之后键入,gdb 将通知您加载的与 _Rep 匹配的类。该列表可以帮助您找到 python 找不到您的std::string class.

我刚刚遇到了您的问题,在我的情况下是 intel c 编译器 icc,它破坏了漂亮的打印。特别是,不合格的 icc 名称std::string会导致:

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;

我为解决我的问题所做的是修改StdStringPrinterprinters.py 中的类,将字符串的非限定名称添加到类型名中以在gdb 中查看。更换线路:

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

有了这个:

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

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

于 2013-01-22T18:08:05.833 回答
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嵌套类型。

于 2012-10-17T18:31:45.150 回答
1

当程序是 LLVM 构建(由 编译clang)时,通常会出现像您上面发布的错误,并且您尝试调试它gdb(应该用于 GCC 构建程序)。理论上,LLVM-build 程序可以被 调试gdb,反之亦然。但是为了避免上面发布的问题,你应该使用lldbif you use clang,并且应该使用gdbif you use g++

于 2017-10-06T17:46:07.247 回答
1

类似于在此处输入链接描述 在 ~/.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
于 2020-03-28T09:56:51.910 回答