如何在 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')
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/libstdcxx
GCC 源代码中:
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 版本。但是,我必须进行以下两项修改:
编辑文件时
~/.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 已经注册。显然它们是在导入阶段注册的。
我必须编辑
std::set
和 的Printers.py 文件std::map
。因为类型_Rep_type
在两者中都是私有的。具体来说,我将 和 中的例程替换children
为std::map
svnstd::set
repo 上 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.conf
3)向您的 中添加一行~/.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
、等plist
)pmap
,其功能是打印 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;
为了解决问题,我修改了StdStringPrinter
Printers.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 修复之后,不需要。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件