如何在GDB中打印STL容器?

Nic*_*son 49 c++ linux debugging gdb stl

我按照GDB维基上的说明安装了用于查看STL容器的python pretty-printers.我~/.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 
Run Code Online (Sandbox Code Playgroud)

但是,当我运行GDB并尝试打印STL类型时,我得到以下内容:

print myString
Python Exception <class 'gdb.error'> No type named std::basic_string<char>::_Rep.: 
$3 = 
Run Code Online (Sandbox Code Playgroud)

任何人都可以对此有所了解吗?我正在运行Ubuntu 12.04,它带有GDB 7.4.

Fei*_*Fei 10

您可以尝试使用以下GDB宏(将其附加到〜/ .gdbinit文件)来打印STL包含类型数据甚至是其数据成员:https://gist.github.com/3978082


Cir*_*四事件 7

它仅适用于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));
}
Run Code Online (Sandbox Code Playgroud)

编译:

g++ -O0 -ggdb3 -o main.out -std=c++98 main.cpp
Run Code Online (Sandbox Code Playgroud)

结果:

(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}
Run Code Online (Sandbox Code Playgroud)

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

(gdb) info pretty-printer
Run Code Online (Sandbox Code Playgroud)

其中包含以下几行:

global pretty-printers:
  objfile /usr/lib/x86_64-linux-gnu/libstdc++.so.6 pretty-printers:
  libstdc++-v6
    std::map
    std::vector
Run Code Online (Sandbox Code Playgroud)

打印机由以下文件提供:

/usr/share/gcc-7/python/libstdcxx/v6/printers.py
Run Code Online (Sandbox Code Playgroud)

它与主要的C ++库软件包一起提供libstdc++6,位于libstdc++-v3/python/libstdcxxGCC源代码中: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))"因此必须在某个地方对其进行硬编码?

自订课程

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


Bin*_*eng 5

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


bar*_*gol 5

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

我使用的是 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
    
    Run Code Online (Sandbox Code Playgroud)

但是,我不得不评论该行register_libstdcxx_printers (None),因为我不断收到错误消息,告诉我 libstdcxx_printers 已经注册。显然,他们是在导入阶段注册的。

  1. 我必须为std::set和编辑 printers.py 文件std::map。由于类型_Rep_type在两者中都是私有的。特别是,我代替常规childrenstd::map,并std::set在从将svn的GCC-4_6分支版本漂亮的打印的版本对应的一个。从那以后没有错误,现在打印出来的东西很好。

希望这可以帮助。


Sco*_*ang 5

您可以尝试此处的脚本,而不是您提到的链接中列出的方法,

执行如下操作:

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)
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

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

例如向量可以通过以下方式访问._M_impl._M_start

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


Omn*_*ous 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 ()
Run Code Online (Sandbox Code Playgroud)

这会查找::Rep基本字符串类型实际是什么的嵌套类型。该错误消息表明您正在使用的任何奇怪库的字符串类实际上并不具有::Rep嵌套类型。