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
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调试界面,还是比老版本看起来更直观。