日更系列:如果gdb打印不出std容器怎么办

2021-12-26 22:55:48 浏览数 (1)

c 中我们经常会使用gdb来截获进程,进行单步调试然后打印出过程中的数据供分析。但是有时候在系统出并不能很好打印出std容器的数据。std比如说一些容器是用红黑树实现,但是打印出红黑树原始结构,这并不是我们想要的东西。

很奇怪的时候,我有两台centos7开发机,有一台可以打印,有一台不可以。为了研究之间的差异,我比较了都是gcc 4.8.5版本

网上找了大量资料说是打印std容器是属于pretty-printer相关的东西,虽然跟gdb版本应该没关系,但是2011年gdb之后的应该就自带这个python脚本功能。

这里的pretty-printer应该跟这个libstdc .so.6有关系。从gdb v6提供了这个pretty-printers文件,最后修改时间是2011年,https://github.com/cfobel/gdb_printers__python/blob/master/libstdcxx/v6/printers.py,所以centos7自带的那个gdb 48理论上应该是支持,但是这里我在用的时候发现没有打印。

在咨询了谷歌之后,发现了一个有用的帖子https://stackoverflow.com/questions/42896196/pretty-print-not-working-for-c-stl-list。

以下这段用引用自该帖子:

很好地打印出数据结构是一些GDB扩展 机制的Python 代码的函数。GDB 手册中有一节介绍了GDB中的漂亮打印

事实证明,对于共享库(也可能对于静态链接库,尚不完全清楚)GDB 有一种方法可以自动加载它们。在我的 Fedora 25 系统上,GDB 自动加载/usr/share/gdb/auto-load/usr/lib64/libstdc .so.6.0.22-gdb.py并且这个文件加载了libstdc 漂亮的打印机。在线手册有一个相当广泛的部分,关于用 Python编写你自己的 GDB 漂亮的打印机

那么我使用以下命令看下是否gdb启动的时候加载了这个pretty-printer。可以打印的机器会输出下列:

我在一台不可以打印的机器就输出。

所以这里我们需要找到系统的printers.py的路径,并使用source加载它。在centos7找到了printers.py所在位置。

⋊> /d/r/l/ws locate printers.py

/usr/local/share/gcc-6.3.0/python/libstdcxx/v6/printers.py

然后在不能打印机器的gdb里面执行下这个命令,source /usr/share/gdb/auto-load/usr/lib64/libstdc .so.6.0.19-gdb.py,然后就可以打印容器了。

更多,当然这里可以设置一个初始化脚本,让gdb启动的时候默认加载脚本

vim ~/.gdbinit制作一个.gdbinit文件,并将所有source命令放在.gdbinit

代码语言:javascript复制
set print pretty on
set print object on
set print static-members on
set print vtbl on
set print demangle on
set demangle-style gnu-v3
set print sevenbit-strings off 


set history save on
set history remove-duplicates 1
set history filename ~/.gdb_history

source /usr/share/gdb/auto-load/usr/lib64/libstdc  .so.6.0.19-gdb.py
set auto-load python-scripts on

这里还添加了一些好用的功能,比如说保存gdb历史命令等。

另外还有个需要说的是,如果gdb版本比较老,我们还可以使用scl enable devtoolset-10 bash使用次新的gcc10.2.1版本。高版本gcc提供了多种颜色的gdb调试界面,还是比老版本看起来更直观。

0 人点赞