50万奖金+官方证书,深圳国际金融科技大赛正式启动,点击报名 了解详情
写点什么

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:111164
用户头像

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

关注

评论

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

数字货币合约交易所系统开发技术

薇電13242772558

区块链 数字货币

8.1文件与磁盘IO:如何把磁盘的读写速度提升十万倍?

张荣召

8.5网络通信基本原理与性能优化

张荣召

架构师第一期作业(第8周)

Cheer

作业

技术分析:AnalyticDB强力支撑双11

数据库 互联网 数据分析 双十一 数据舱

缓存与数据库一致性策略

码界西柚

建行数字债券允许比特币交易?官方回应了!业内人士:交易架构的创新值得赞赏

CECBC

比特币 债券

架构师训练营 1 期 - 第八周作业(vaik)

行之

微服务下,使用 ELK 进行日志采集以及统一处理

华为云开发者联盟

微服务 Kibana ELK

阿里P10带你深度剖析:淘宝网是如何基于Spring Cloud微服务框架搭建大型电商平台设计

Java架构追梦

Java 架构 面试 微服务 SpringCloud

云图说|云上攻击早知道,少不了这个“秘密武器”!

华为云开发者联盟

安全 云服务 云端

作业--week08

张荣召

Mock服务设计与实现:MySQL驱动字节码修改增强

华为云开发者联盟

MySQL 数据库 sql

企业级软件的核心价值

Learun

敏捷开发 快速开发 企业开发 企业应用

8.3红黑树原理与性能特性

张荣召

飞书的「背道而驰」

ToB行业头条

简要分析近几年商业软件开发平台的现状

Learun

企业 企业开发 企业应用

用废旧纸箱DIY智能宠物喂食器!旅行在外远程投喂“二狗子”

智能物联实验室

物联网 DIY 智能硬件

区块链USDT系统开发解决方案,USDT支付系统技术开发

13530558032

企业级软件的核心价值

Marilyn

敏捷开发

函数式编程:如何高效简洁地对数据查询与变换

华为云开发者联盟

编程 面向对象 数据处理

重磅发布!Flink Forward Asia 2020 在线峰会预约开启!

Apache Flink

flink

区块链赋能供应链金融 | 应用优势与四类常见模式

CECBC

区块链 供应商审核

数字货币交易所开发定制,币币撮合交易开发商

13530558032

8.2常见数据结构与Hash表原理分析

张荣召

Week 8 命题作业

阿泰

简要分析近几年商业软件开发平台的现状

Marilyn

快速开发 企业开发

自己写歌怎么编曲?4款超好用编曲软件推荐

奈奈的杂社

编曲 音频制作 midi daw

区块链带来的业务流程优化是数字化转型最深层次的变革

CECBC

区块链 数字化

区块链钱包APP开发,开发搭建数字货币钱包

13530558032

8.4经典算法

张荣召

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