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

2024-10-29 08:35:00
admin
原创
86
摘要:问题描述:我按照GDB wiki 上的说明安装了 python 漂亮打印机,用于查看 STL 容器。我的~/.gdbinit现在看起来像这样:python import sys sys.path.insert(0, '/opt/gdb_prettyprint/python&#03...

问题描述:

我按照GDB wiki 上的说明安装了 python 漂亮打印机,用于查看 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 = 

有人可以解释一下吗?我正在运行带有 GDB 7.4 的 Ubuntu 12.04。


解决方案 1:

它只适用于 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('
'.join(sys.path))"`所以它必须在某处进行硬编码?

自定义类

请参阅如何定义自定义toString方法并调用它:使用 GDB 打印 C++ 类对象

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

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

在未优化的代码上它可以工作:使用 gdb 检查标准容器(std::map)的内容

解决方案 2:

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

解决方案 3:

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

我使用的是 gcc-5.2,因此我从 svn repo 下载了 pretty Printer 的 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在两者中都是私有的。具体来说,我将 和 中的例程替换childrenstd::mapsvn std::setrepo 上 gcc-4_6-branch 版本的 pretty Printer 版本中的相应例程。从那以后再也没有出现错误,现在东西打印得很好。

希望这有帮助。

解决方案 4:

类似于在这里输入链接描述
在〜/ .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

解决方案 5:

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

解决方案 6:

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

请按如下方式操作:

1) 将脚本下载至/your/path。将其命名为your_name.conf

2)~/.gdbinit如果您没有文件,请将文件添加到主目录。

source /your/path/your_name.conf3)向您的 中添加一行~/.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添加了几个命令(pvector、等plistpmap,其功能是打印 STL 的元素。它还添加了print pretty,产生了如下的良好格式:

在此处输入图片描述

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

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

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

解决方案 7:

如果您info type _Rep在 Python 异常后输入内容,gdb 将通知您有关与 _Rep 匹配的已加载类的信息。该列表可以帮助您找到 Python 无法找到您的原因std::string class

我刚刚遇到了你的问题,在我的例子中是英特尔 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 中的类,将字符串的非限定名称添加到 typename 中,以便在 gdb 中查找。替换以下行:

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

替换为:

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

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

解决方案 8:

像您上面发布的错误通常出现在程序是 LLVM 构建的(由 编译clang)并且您尝试使用 对其进行调试gdb(应该用于 GCC 构建的程序)时。理论上,LLVM 构建的程序可以通过 进行调试gdb,反之亦然。但为了避免出现上述问题,lldb如果您使用,则应该使用 ,如果您使用 ,则clang应该使用。gdb`g++`

解决方案 9:

我认为您正在使用非 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嵌套类型。

解决方案 10:

我的系统也遇到了这个问题。

对我来说,解决方法如下

在 ~/.gdbinit 中

python
import sys
sys.path.insert(0, '<path/to/gcc/dir>/GCCcore/9.3.0/share/gcc-9.3.0/python/')
exec(open("<path/to/gcc/dir>/GCCcore/9.3.0/lib64/libstdc++.so.6.0.28-gdb.py").read())
end

问题是python包含漂亮打印机的文件夹不是 Python 搜索的一部分path(就像您通常需要将 Python 模块位置添加到 一样$PYTHONPATH)。第一个命令完成了这一点。下一个问题是现在需要加载漂亮打印机。GCC 在我的系统上提供了一个脚本来执行此操作GCCcore/9.3.0/lib64/libstdc++.so.6.0.28-gdb.py。第二个命令“获取”此脚本,它将加载打印机。


附言

在进行此修改之前我还收到以下错误:

warning: File "<path/to/gcc/dir>/GCCcore/9.3.0/lib64/libstdc++.so.6.0.28-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".

可以通过将以下内容添加到 gdb 初始化文件来修复此问题

add-auto-load-safe-path  <path/to/gcc/dir>/software/GCCcore/9.3.0/

但是,这仍然不允许漂亮的打印机工作(因为路径仍然没有设置),并且在上述 python 修复之后,不需要。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   681  
  在项目管理领域,集成产品开发(IPD)流程以其高效、协同的特点,被众多企业视为提升产品竞争力的关键。IPD流程强调跨部门、跨职能的紧密合作,以确保产品从概念到市场各个环节的无缝衔接。然而,实现这一目标并非易事,它需要企业深刻理解并掌握IPD流程中的跨部门协作艺术。本文将深入探讨IPD流程中跨部门协作的三个关键点,旨在为...
IPD项目管理咨询   9  
  掌握IPD流程图:提升团队协作的关键路径在当今快速变化的商业环境中,团队协作的效率与效果直接关系到项目的成功与否。集成产品开发(Integrated Product Development,简称IPD)作为一种先进的研发管理理念,通过跨部门、跨领域的协同工作,能够显著提升产品开发的速度与质量。而IPD流程图,则是这一理...
IPD流程阶段   9  
  IPD流程概述:理解其核心价值与实施背景集成产品开发(Integrated Product Development,简称IPD)是一种先进的产品开发管理理念,它强调跨部门协作、市场导向和快速响应变化的能力。IPD流程不仅关注产品本身的技术创新,更注重将市场、研发、生产、销售等各个环节紧密集成,以实现产品从概念到市场的高...
华为IPD是什么   7  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程以其跨部门协作、高效决策和快速响应市场变化的特点,被众多企业视为提升竞争力的关键。然而,实践IPD流程并非易事,项目管理中的种种错误往往阻碍了其效果的充分发挥。本文旨在深入探讨如何在实施IPD流程时避免这些常见错误,...
IPD框架   7  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用