写点什么

Rubinius 全速调试器技术内幕

  • 2008-01-29
  • 本文字数:1534 字

    阅读完需:约 5 分钟

Ruby 的调试器支持早已有之——长久以来,Ruby 发行时都附带着一个命令行调试器。不过,调试器的速度一直是个问题。通常,Ruby 调试器使用诸如 Ruby 的回调(callback)块或通过在 Ruby 代码执行前调用函数来实现。回调会检查线程是否挂起或该行代码是否存在断点。

Ruby 的自带调试器使用 Ruby 实现,包含一个通过 set_trace_func 设置的 Ruby 块。这一方法的更快速版本则采用了 C( ruby-debug Cylon debugger )和 Java( jruby-debug ) 作为实现语言。然而,无论回调执行的多快,这种解决方案的问题都始终存在:只要 debugger 一启动,所调试 Ruby 程序的每一行代码都会承受额外的开销。

对于这一问题的理想解决方案应该是不引入 _ 额外开销 _,然后在遇到断点时将线程挂起。也就是在被触发前,断点不会带来(CPU 时钟周期方面的)任何代价。这正是 Rubinius 的全速调试器所采用的方案——这里的“全速”意指程序即便是在被调试时,也能保持正常的运行速度。

如下的特性使得Rubinius调试器的全速成为可能:

  • 将所有的 Ruby 代码转换成 shotgun 虚拟机所执行的指令(op_codes)——目前通过op_code 解释器执行

  • 全速调试功能引入了一条名为 yield_debugger 的新指令——当该指令执行时会通知位于一个已定义 channel 之上的调试器线程(channels 是一种管道,也就是说从一端放入其中的数据可以在另一端接收到)

  • 方法的字节码可以被访问——实际上这一做法通常比较细微。这里示例一个String 类的``to_s方法: m = "".method(:to_s) cm = b.compiled_method<br></br># this yields an array of InstructionSet::Opcode objects cm.bytecodes.decode

  • 多种工具方法为将指令偏移对应到行号提供帮助,例如 CompiledMethod 的 first_ip_on_line 方法等。

有了这个功能之后,可以非常简单地在某个方法的特定行中设置断点

  • 获取这个方法的 Method 对象和对应的 CompiledMethod 对象
  • 指出这个断点行的第一条指令的位置
  • 把该位置的指令变成yield_debugger。原先的指令会被保存在一个用于管理的数据结构中
  • 在到达这个断点并且用户选择继续执行之后,原先的指令会被执行,而后会按正常的序列执行代码

这个功能已经存在一段时间了(参见 InfoQ: Evan Phoenix 访谈 - 深入 Rubinius:线程、对象空间、调试)。不过因为Adam Gardinerd 的工作,这个全速调试器现在可以被一般用户使用了。Adam Gardiner 为 Rubinius debugger 增加了基于命令行的用户界面以 及一些必要的命令。不仅如此,他编写的功能允许用户进行逐行单步调试。要使用这个功能只需要把当前断点的下一行也设为断点即可。当然,这个功能还需要了解 当前行是不是方法中的最后一行。不过在 Rubinius 中通过获取调用当前断点方法的句柄,这个信息也是可以得到的。因为上下文对象,例如方法活动栈,拥 有一个 sender 方法实现了这个功能。

调试器的使用很简单。在您装好了 Rubinius 后(查看如何检出并编译Rubinius ),通过如下方式启动 irb

shotgun/rubinius 然后执行: Rubinius::VM::debugger(注意:对于目前版本,输入debugger也同样可以工作)。然后您将会进入到调试器的文本界面 - 可用的命令列表可以通过"?"命令获得,包括管理断点和诸如查看 op_codes 和其他方法中的 Ruby 源代码这样的特性。

比起那些依靠 trace 方式调试的 Ruby 实现(不论这些实现的速度有多快),全速调试器都使得 Rubinius 具有了独特的优势。同样值得注意的是:除了整个 yield_debugger 指令使用了一些 C 代码,绝大多数 Rubinius 调试功能都是内建的。

您尝试过 Rubinius 了吗?您是否了解应如何有效利用 Rubinius 清晰可见的内部结构,例如可以在运行时刻访问并修改字节码、查看调用栈?

另:查阅 InfoQ 之前关于 Rubinius 的相关报道

查看英文原文: Inside the full speed Rubinius debugger

2008-01-29 23:111146
用户头像

发布了 24 篇内容, 共 43056 次阅读, 收获喜欢 0 次。

关注

评论

发布
暂无评论
发现更多内容

TEM安装与功能测试

TiDB 社区干货传送门

安装 & 部署 性能测评 TEM 试用

Apache Flink 2.1.0: 面向实时 Data + AI 全面升级,开启智能流处理新纪元

Apache Flink

大数据 flink 实时计算 实时计算Flink

民航领域数据分类分级怎么做?|《民航领域数据分类分级要求》标准解读

原点安全

TEM on 腾讯云安装实践实录

TiDB 社区干货传送门

版本测评 新版本/特性发布 8.x 实践 敏捷模式 TEM 试用

TiDB 集群运维管控平台 TEM on Cloud(腾讯云)试用体验

TiDB 社区干货传送门

集群管理 版本测评 8.x 实践 TEM 试用

TEM试用分享-监控自建TiDB集群

TiDB 社区干货传送门

安装 & 部署 8.x 实践 TEM 试用

Mac M1 部署 TiDB

TiDB 社区干货传送门

安装 & 部署 TiDB第四届征文-运维开发之旅

汽车抬头显示的智能化旅程

脑洞汽车

AI

AI+评查,助力烟草企业提质增效

中烟创新

亚马逊商品详情API开发指南

tbapi

亚马逊API 亚马逊商品详情API 亚马逊数据接口

小公司管理:警惕大厂的“成功方程式”

禅道项目管理

TEM on Cloud 试用指南:值得 DBA 花时间吗?

TiDB 社区干货传送门

社区活动 版本测评 安装 & 部署 TiDB第四届征文-运维开发之旅 TEM 试用

TEM on 腾讯云试用

TiDB 社区干货传送门

TEM 试用

中烟创新灯塔大模型应用开发平台入选工信部“政务大模型应用典型案例”

中烟创新

扣子可以发布到小米搞钱了!手把手教程来了丨coze开发者瓜分亿级流量池指南

阿星AI工作室

开发者 产品经理 小米 扣子

合同总是延误?8款好用的电子签章工具推荐给你

数字工具研究

灵活分库分表,面试的时候这么说,加分!

王中阳Go

数据库 后端

四步破解日志平台数据孤岛困局,核心驱动企业高效运营

日志易

日志管理 日志易

前瞻与回顾:长期个性化对话代理的反射式记忆管理技术

qife122

强化学习 对话系统

「迁移急救包」全云平台无缝迁移云效实操手册

阿里巴巴云原生

阿里云 云原生 云效

中烟创新BI数据大屏赋能烟草专卖和营销,激活烟草企业数据生产力

中烟创新

数新智能 CTO 原攀峰:DataCyber 面向 AI 时代的多模态数据湖设计与实践

数新网络官方账号

企业AI落地实践(三):使用 AI 网关解决 AI Agent 与 LLM 的交互挑战

阿里巴巴云原生

阿里云 云原生 LLM AI Agent

医疗AI安全:基于可解释性的伪相关检测与缓解框架

qife122

人工智能 模型可解释性

超强的运维管理平台,TEM on 腾讯云安装 + TiDB 集群实践

TiDB 社区干货传送门

安装 & 部署 TiDB第四届征文-运维开发之旅 TEM 试用

「迁移急救包」全云平台无缝迁移云效实操手册

阿里云云效

阿里云 云原生 云效

TEM on 腾讯云使用体验

TiDB 社区干货传送门

集群管理 新版本/特性发布 安装 & 部署 TEM 试用

漏洞赏金猎人指南:Web应用安全测试与内网资产发现实战

qife122

渗透测试 漏洞挖掘

ToDesk云电脑 vs 顺网云 vs 海马云:谁才是5090显卡云电脑的真王者?

袁袁袁袁满

阿里云 API 网关 x OKG:游戏连接治理的「最后一公里」

阿里巴巴云原生

阿里云 云原生 API OKG

紧急救火与战略开发:软件工程中的关键抉择

qife122

软件工程 技术债务

Rubinius全速调试器技术内幕_Ruby_Werner Schuster_InfoQ精选文章