ruby 调试_Ruby调试器

浦泳
2023-12-01

ruby 调试

关于Ruby的一个误解在Ruby社区内部和外部都非常普遍。 误解是:Ruby没有调试器。 有人认为这是Ruby的问题。 其他人试图将这种缺乏调试工具的现象解释为明智和良好的作风

但是,无论从哪个角度来看:这仍然是一个误解 。 Ruby确实有调试工具-其实不少。 让我们看一下各种Ruby实现中的可用工具,包括调试GUI,调试器实现和调试支持。

什么是调试器?

首先,让我们澄清一下“调试器”的实际含义。

调试GUI和界面

当然, 交互式调试器最重要的部分(至少对于用户而言)是用户界面。 提供了用于Ruby调试器的命令行界面,例如Ruby标准库Rubinius调试器附带的命令行界面。 尽管这些当然可以调试代码,但是它们也使设置断点或查看实际情况变得很繁琐。 集成开发环境。 集成部分对于调试很重要,因为IDE可以集成代码编辑和调试工具。 可以直接在源代码编辑器中完成断点的管理-与获取一段代码的行号,转到命令行调试器并在此手动输入断点相比。 基于IDE的行(例如基于行的步进)功能也变得更加有用,该IDE在正确的行处打开当前堆栈帧的文件。 EclipseMonkey扩展允许使用JRuby编写脚本 。 由于这些脚本与Eclipse IDE在同一JVM中运行,因此可以访问Debugger实例并对其进行控制。

调试器协议或连接到后端

将调试器用户界面(如IDE)与调试器后端连接的一种简单方法是使用命令行界面,并通过stdin / stdout / stderr流进行控制。 这样,编辑器或IDE的调试器支持可以控制调试器,但同时使用户更容易管理断点。 telnet并连接到Ruby调试器。 debug-commonsDBGp命令中的协议由单行字符串和XML响应组成。

虚拟机支持或调试后端

为了允许诸如断点之类的功能起作用, 语言运行时必须至少提供最少的支持来监视和控制执行。 这可以像Ruby的跟踪功能一样小:在执行一行Ruby代码之前,Ruby会调用一个通过调用set_trace_func设置的回调函数。 传递给此函数的参数包括有关Ruby即将执行的代码行的环境的信息,例如它的行号,所在文件的名称,其类等。这足以实现断点功能 :file名称和行号允许检查已注册断点的列表,如果该行已注册一个。 只是通过不从回调返回而暂停 -Ruby运行时只能在回调返回后才能继续。 在此基础上,可以实现步进等功能。 在断点行的位置修改加载的代码 (无论是AST还是操作码) 。 某些语言运行时具有内置的调试支持,该调试支持与其执行机制集成在一起。 Java和.NET二进制文件都可以附带调试信息(即,从文件和行号到字节码中位置的映射),然后内置调试支持将其用于实现调试器功能。 例如,在Java空间中,JVM附带了用于访问此功能的JVM工具接口(JVM TI )和用于连接到JVM的Java调试线协议(JDWP )。 Rubinius调试器,它使用Ruby代码的可访问和可修改的操作码(Rubinius在执行之前将Ruby源代码编译为操作码)。 通过将常规操作码与特殊操作码交换来设置断点,该特殊操作码会挂起当前线程并通知调试器堆栈的更高层。

Ruby实现的调试器和IDE支持

通过基本设置,让我们看一下可用的东西,首先从Matz的Ruby实施(MRI)开始 ,这是最常用和受支持的Ruby实施。 之后,我们将研究JRuby,Rubinius和IronRuby的情况-这些Ruby实现的工具支持以及它们与MRI不同的地方,无论是工具支持还是性能。

Ruby/核磁共振

调试后端

Ruby 1.8.x或MRI是用C编写的官方Ruby解释器。此版本的Ruby提供了许多调试选项。 跟踪调试器可用,标准库附带其Ruby版本。 但是,有更快的实现方式。 一种是ruby-debug ,它是使用本机扩展实现的。 Steel IDE中的RubyCylon调试器 。 它还使用本机代码来实现,以实现该功能,并使用Ruby钩子来获取有关方法调用等事件的通知。根据SapphireSteel的基准测试 ,Cylon调试器明显比用Ruby编写的调试器快,也比ruby-调试。

图形用户界面

许多Ruby IDE提供调试支持。 基于Eclipse的RDT(现在是Aptana和RadRails的一部分)已经有很长时间的调试支持,首先连接到基于Ruby的跟踪调试器,然后再支持ruby-debug。 RDT的调试协议已被纳入 Netbeans Ruby中用于提供调试的debug-commons项目中。 Ruby IDE空间中的另一个旧计时器是ActiveState的Komodo ,它基于DBGp协议构建以连接到其协议。 Eclipse DLTK Ruby (也是CodeGear 3dRail的基础)是另一个利用Eclipse调试器GUI的IDE。 DLTK还使用DBGp连接到后端。 SapphireSteel的Ruby in Steel包含调试器GUI,可使用其Cylon调试器进行快速调试。 IntelliJ Ruby Roadmand将调试支持列为未来的项目

Ruby

调试后端

基于常规跟踪的Ruby调试器也可以在JRuby中使用。 此外,还有一个更快的版本jruby-debug (也托管在debug-commons项目中)使用Java作为实现语言,而不是Ruby,以减少每行执行的开销。 JRuby调试后端来自SapphireSteel 。 已经以其定制的MRI快速Cylon调试器提及了该公司。 与jruby-debug不同,SapphireSteel的解决方案使用Java和本地代码(通过JNI)作为调试器后端。

图形用户界面

支持set_trace_func调试的Ruby IDE也可以与JRuby一起使用,Netbeans和Apatana也附带jruby-debug支持。 跨语言调试支持显然为每个使用JRuby的人带来了额外的好处,这些人不仅将JRuby用作普通的Ruby运行时,而且使用Ruby编写Java类脚本。 在这种情况下,跨语言调试很有用-即在Ruby代码调用Java代码时显示Ruby和Java堆栈以及变量。

鲁比尼乌斯

调试后端

Rubinius当然已经走了很长一段路-特别是在过去的几个月中,就调试性能而言,它的调试支持从不存在跃居到Ruby领域的前端。 全速Ruby调试器允许运行启用了调试的Ruby程序,而没有其他解决方案的性能开销,如上所述或在链接的新闻中。 可访问已加载的Ruby代码的ParseTree以及堆栈跟踪 。 内省功能进一步扩展,例如使用SendSites 。 SendSites代表消息发送的站点(“方法调用”),并且可以链接到该方法。 这样可以在运行时确定已加载代码的配置,而且还可以作为概要分析或代码覆盖工具。 每个发送的消息都会增加SendSite的计数器; 由于此信息可用于常规Ruby代码,因此编写简单的探查器或至少一个代码覆盖率工具仅需几行代码。

图形用户界面

目前,Rubinius调试器的用户界面是命令行界面,该界面可以管理断点,单步执行,还可以查看运行Ruby代码或其源文件的操作码。 有用的命令是sexp [method] ,它返回[method]的AST的ParseTree s-expr表示形式。 (忽略该参数会将当前方法的AST显示为ParseTree s-expr)。 这是非常有用的信息,特别是对于使用元编程的代码-运行时生成的代码显然没有代码。 能够查看生成的已加载代码可以帮助调试执行元编程的代码。 查看s-expr是从尝试猜测所生成的代码的作用而迈出的一步-通过回退基于ParseTree的工具(如Ruby2Ruby) ,它会更加方便,后者使用s-expr并将其格式化为Ruby源代码。

铁Ruby

IronRuby通过生成MS IL代码以.NET平台为目标。 它利用DLR,该系统收集语言实现的常用功能,例如从表达式树生成MS IL等。

调试后端

DLR生成.NET MS IL,并且还可以生成MS IL调试信息,这意味着IronRuby可以同时使用.NET调试工具和Visual Studio调试器GUI。

图形用户界面

可以使用Visual Studio,但是Ruby的Steel IDE中的SapphireSteel Ruby(也基于Visual Studio)具有对IronRuby开发的支持。 调试功能应该在将来的版本中可用。

其余领域

本文展示了一些当前可用于Ruby的调试工具的示例,但并未声明其完整性。 IDE中还提供了其他GUI和后端,例如ActiveState的Komodo或对Ruby实现或调试功能提供不同级别支持的后端。 尽管未提供Ruby实现XRuby ,但它具有调试支持 。 也没有提到Ruby 1.9,尽管它已经正式发布,但它似乎仍在大量开发中。 由于Ruby 1.9的VM也使用字节码解释器,因此可能有类似于Rubinius的方案。 免责声明 :替代Ruby实现和调试支持的开发现在正在快速发展。 因此:将本文作为Ruby中调试支持的概述-在您阅读本文时,Ruby实现和工具的实际调试支持可能已经改变和改进。

翻译自: https://www.infoq.com/articles/ruby-debuggers-survey/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

ruby 调试

 类似资料: