02_gdb_pretty_printer加载原理

gdb prettp printer加载原理

背景

如何在你还记得这两张图,那么就好办了,来自 01_gdb容器可视化概论:

在这里插入图片描述

在这里插入图片描述

如果你不清楚这两张图的含义,请查看: 01_gdb容器可视化概论

pretty printer 加载方式

我们使用系统 gdb 对项目进行调试,然后来到调试控制台,我们可以看到如下信息,gdb在加载动态库:

Breakpoint 1, main (argc=2, argv=0x7fffffffdca8) at /home/haorui/haorui/web_tc/src/main.cpp:14
14 int main(int argc, char** argv) {
Loaded '/lib/x86_64-linux-gnu/libpthread.so.0'. Symbols loaded.
Loaded '/usr/lib/x86_64-linux-gnu/libstdc++.so.6'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libm.so.6'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libgcc_s.so.1'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libc.so.6'. Symbols loaded.
Execute debugger commands using "-exec <command>", for example "-exec info registers" will list registers in use (when GDB is the debugger)

我们可以暂时记一下,这里面有依据 Loaded '/usr/lib/x86_64-linux-gnu/libstdc++.so.6'. Symbols loaded.

然后我开启讲解一下 gdb 加载插件的六种方式吧,说是 pretty printer 并不是特别好,应该称之为插件,这里使用 auto-load,你可以看到以下的内容:

gdb-scripts:  Auto-loading of canned sequences of commands scripts is on.
libthread-db:  Auto-loading of inferior specific libthread_db is on.
local-gdbinit:  Auto-loading of .gdbinit script from current directory is on.
python-scripts:  Auto-loading of Python scripts is on.
safe-path:  List of directories from which it is safe to auto-load files is $debugdir:$datadir/auto-load.
scripts-directory:  List of directories from which to load auto-loaded scripts is $debugdir:$datadir/auto-load.

在这里插入图片描述

我个人会了解的也只有 gdb-scriptslocal-gdbinitsafe-path,其中 safe-path 应该是最合理的解决方案了。

以上就是 gdb 加载插件的六种途径,像网上大多使用的基本是通过 local-gdbinit 的方式加载插件,而 ubuntu 则是使用 safe-path 加载插件。

auto load 顾名思义就是自动加载,不需要你人为地加载,我们可以使用 info auto-load 查看已经加载的插件,打印出来的内容如下:

gdb-scripts:  No auto-load scripts.
libthread-db:  No auto-loaded libthread-db.
local-gdbinit:  Local .gdbinit file was not found.
python-scripts:  
Loaded  Script                                                                 
Yes     /usr/share/gdb/auto-load/lib/x86_64-linux-gnu/libpthread-2.27.so-gdb.py 
Yes     /usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25-gdb.py

这两个动态库是我程序中使用的,你可以看看这个目录下是不是有一个 auto load 的文件夹,如下:

在这里插入图片描述

这里简单地解释一下其加载规则,直接在下图中给出了,以加载 /usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25-gdb.py 为例:

在这里插入图片描述

这里给出原理是因为我怕你直接 copy 这个给远程调试的 gdb 使用了,它们是不能混用的,当然你说改一改能不能用,答案是可以的;但是我看了一下,有点难改,改了一下午没搞定,就换方案了。

但是本地 gdb 是有效果的,比如我把这个 auto-load 拷贝给我源码编译本地调试用的 gdb ,那么应该可以做到容器的可视化。

在这里插入图片描述

远程调试 gdb pretty printer 配置

虽说我们知道本地或者系统的 gdb 可以通过 auto-load 的方式自动加载 pretty printer 记载对应的 printer,但是你也要明白 auto-load 是不能够混用的。

但是巧就是巧了,基本所有的库的 py 脚本都写得一样,我们看看 libstdc++.so.6.0.25-gdb.py 这个脚本是怎么写的吧,其中关键四行:

# Call a function as a plain import would not execute body of the included file
# on repeated reloads of this object file.
from libstdcxx.v6 import register_libstdcxx_printers
register_libstdcxx_printers(gdb.current_objfile())

这其实就是你在其他博客哪里看到开启 gdb pretty printers 的方式。

我们看到了自动加载的脚本是如何加载的,那虽然自动不了,但是我可以手动加嘛,这是小问题,使用 local-gdbinit 这种方式实现,你在你的 ~ 目录的 sharetouch .gdbinit,然后在其中添加:

python
import sys
# 借用 ubuntu 系统自带的,按照自己的填写
sys.path.insert(0, '/usr/share/gcc-8/python/libstdcxx/v6')
sys.path.insert(0, '/usr/share/gcc-8/python')
# 修改成你自己安装的 gdb 路径
sys.path.insert(0, '/home/haorui/tools/arm-hisiv600-linux-gdb/share/gdb/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)

然后我们远程调试看看效果,如下:

在这里插入图片描述

可以看到 165 of 165 printers enabled, 不是 171 ,少了 6 个是来自线程库的。

不过原理懂了,那就可以改嘛,小问题,利用 source 一脚把 py 脚本提起来:

source  /usr/share/gdb/auto-load/lib/x86_64-linux-gnu/libpthread-2.27.so-gdb.py
python
import sys
sys.path.insert(0, '/usr/share/gcc-8/python/libstdcxx/v6')
sys.path.insert(0, '/usr/share/gcc-8/python')
sys.path.insert(0, '/home/haorui/tools/arm-hisiv600-linux-gdb/share/gdb/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)

在这里插入图片描述

171,一个不多一个不少,说明什么呢,我们可以从 auto-load 里面去偷脚本,虽然它们可能不是通用的,但是绝大部分是通用的;而 auto-load 里面的文件大多数都是安装库的时候自动装上去的,也就是 auto-load 中的文件不是一成不变的。

同时研究其 py 脚本的实现,你可以实现自己的 printer, 还是有很多地方需要这个东西的。

总结

其实这是一篇比较不严谨的文章,毕竟我才刚刚接触 gdb 命令行工具,而且我也不打算继续深入,毕竟对我没什么太大的实际价值,我要找的东西已经找齐了;但是对你而言可能不够,你可以阅读一个 GDB 参考手册, 下载一份还是挺有价值的,这些东西都可以在里面找到答案。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值