问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Ruby程序能不能像Java,C等那样单步调试

发布网友 发布时间:2022-04-18 21:02

我来回答

2个回答

热心网友 时间:2022-04-18 22:32

有一个关于Ruby的误解在Ruby社区内外广泛流传,即:Ruby没有调试器。有些人说这是Ruby的一个问题。其他人则试图将所谓的缺少调试工具解释为智慧之举和良好风格。这些观点都是误解。Ruby明明是有调试工具的——实际上有很多。让我们来看一看这些现有的工具,包括调试GUI、调试器实现和各种Ruby实现中的调试支持。
什么是调试器?
首先,让我们搞清楚“调试器”实际上涉及了哪些东西?

调试的GUI和接口
当然了,交互式调试器最重要的部分——至少对于用户来说——是用户接口。用户可以使用Ruby调试器的命令行接口,例如和Ruby标准库一起提供的Rubinius调试器。它显然可以用来调试代码,只不过设置断点或查看运行状态会比较麻烦。
IDE虽然有时在Ruby世界中不太受推崇,但它无疑令调试变得更简单了——毕竟,IDE就是集成开发环境。集成对于调试来说很重要,而IDE正是把代码编辑和调试工具整合在一起了。你可以在源代码编辑器中直接管理断点——而不用记下代码的行号,进入命令行调试器中,然后手工设置断点。在IDE中,诸如基于行的单步调试之类的功能也更加实用,可以正确的找到所打开的文件的栈结构和所在行。
带有嵌入式脚本支持的IDE还允许对脚本进行调试。例如 ,Eclipse的EclipseMonkey扩展支持用JRuby写成的脚本。由于这些脚本和Eclipse IDE都运行在同一个JVM上,由此调试器实例便可以被访问和控制了。
调试器协议还是连接到后端
把像IDE这样的调试器用户接口和调试器后端连接起来的一个简单方法是:使用命令行接口,并通过标准的stdin/stdout/stderr流来进行控制。这样,编辑器或者IDE的调试器支持就可以控制调试器,同时也让用户管理断点变得更加方便了。
另外一个方法是采用线路(wire)协议,它允许通过某种模式的进程通讯(IPC),现在一般是通过TCP/IP来连接到调试器。基于网络的协议还允许GUI和调试器分布在不同的机器上,也就是说可以使用本地的用户接口来对远程机器进行调试。
基于文本的或者至少基于文档的简单调试协议也允许使用任何语言来编写调试进程脚本。实际上,连接到Ruby调试器和打开telnet一样简单。debug-commons和DBGp命令的协议就是由单行字符串和XML应答构成的。
VM支持还是调试后端
为了支持断点等功能,语言运行时至少得提供监视和控制执行的支持。可以简单地像Ruby的跟踪(tracing)功能一样:在一行Ruby代码执行之前,Ruby会调用一个叫做set_trace_func的回调函数。传过去的参数包括即将执行的那行代码的环境信息,比如行号,所属文件的名字和所属的类等等。这些信息就足以实现断点功能了:在一个断点注册表里面检查文件名和行号,看看是否被注册了。
当遇到一个断点时,执行就被挂起,只要不从回调中返回即可——Ruby运行时只能在回调返回后才能继续运行。基于这些,就可以实现单步调试等功能了。
虽然使用跟踪功能可以实现一个调试器,但是在执行每一行之前都要先执行跟踪回调,显然太慢了。理想地解决方案是仅在执行有断点的行时才引发断点处理。运行时可以通过修改已加载的代码来实现此功能——不论是AST还是操作码(opcodes)——在有断点的行上。有些语言的运行时提供了内建的调试支持,与执行机制整合在一起。Java和.NET的二进制代码都提供调试信息(即从文件和行到字节代码位置一个映射),让内建的调试支持能使用这些信息来进行调试。在Java世界中,例如,JVM配合JVM工具接口(JVM TI)一起实现了这个功能以及用来连接到JVM的Java调试线路协议(JDWP)。
还有一个方法是Rubinius调试器所使用的,它使用可访问和可修改的Ruby代码中的操作码(Rubinius把Ruby源代码先编译成操作码然后再执行)。
通过把一个一般操作码替换成一个特殊操作码来设置一个断点,而这个特殊操作码则用来挂起当前进程并通知调试堆栈中的高层。 通过设置大量的基础体系和管理数据结构以供语言来访问,语言本身就可以用来建立调试机制。
各种Ruby实现的调试器和IDE支持
有了以上基础,再让我们来看一看现有的调试器。从用得最广、支持得也最多的Matz的Ruby实现(MRI)开始。之后让我们再看一看JRuby、Rubinius以及IronRuby的现状——看看这些Ruby实现的工具支持,还有它们与MRI以及其工具支持和性能的区别。
Ruby/MRI
调试后端
Ruby 1.8.x,也就是MRI,是官方的Ruby解释器,是用C语言实现的。我们最常见的调试器就是针对它的。这个跟踪调试器是配合它的Ruby版本以及标准库一起使用的。另外还有更快的实现。比如ruby-debug,它是使用本地扩展来实现的。
还有一个选择是随SapphireSteel的Ruby in Steel IDE提供的:Cylon debugger。它也是通过本地代码来实现功能,使用Ruby钩子来获得诸如方法调用等事件通知而完成的。 SapphireSteel的标准测试表明,Cylon调试器比用Ruby写的调试器快得多,也比ruby-debug要快。
GUI
许多Ruby IDE提供都调试功能。基于Eclipse的RDT (现在是Aptana和RadRails的一部分)在很久以前就开始提供调试支持了,一开始是连接到基于Ruby的跟踪调试器上,后来转而支持ruby-debug。RDT的调试协议被分解到了debug-commons项目中,该项目用于Netbeans Ruby,以提供调试功能。在Ruby IDE世界中还有一个古老的ActiveState's Komodo,它是基于DBGp协议的。另外一个能与Eclipse的调试器GUI抗衡的IDE是Eclipse DLTK Ruby,它也是CodeGear 3dRail的基础。DLTK也使用DBGp来连接到后端。SapphireSteel的Ruby in Steel包含了一个调试器GUI,它允许使用Cylon调试器来进行快速调试。
这些IDE的功能虽不尽相同,但至少都提供了断点、单步调试和变量查看功能。 注意:尽管IntelliJ在它们的IDE中提供了编辑Ruby功能,但在IntelliJ Ruby的蓝图中调试支持是作为一个未来项目的。
JRuby
调试后端
基于跟踪的常规Ruby调试器也能用于JRuby。除此之外,更快的版本是jruby-debug(也属于debug-commons项目),它是用Java而不是Ruby语言来实现的,从而减少了每行的执行开销。
还有一个新的来自SapphireSteel的JRuby调试后端。刚才提到了这个公司,他们还做了MRI的快速Cylon调试器。和jruby-debug不同,SapphireSteel的解决方案同时使用Java和本地代码(通过JNI)实现了调试器后端。
GUI
支持set_trace_func调试的Ruby IDE也能用于JRuby。另外Netbeans和Apatana也提供了jruby-debug支持。对于那些不止把JRuby当作普通Ruby运行时、还要用Ruby调用的Java类的人来说,显然很需要支持跨语言的调试。当Ruby核调用Java核时,最好同时显示Ruby和Java的堆栈和变量。
SapphireSteel IDE使用他们自己实现的后端和通讯协议,而不是基于ruby-debug或者jruby-debug,这意味着它是被绑定在Ruby in Steel IDE中的。
Rubinius
调试后端
毫无疑问,Rubinius取得了长足的进步——特别是在过去的几个月中,它的调试支持从没有一跃成为Ruby界中的佼佼者(根据调试性能表现)。全速Ruby调试器允许伴随调试运行一个Ruby程序,而没有其他方案中的那种性能消耗,正如前面解释的或者链接新闻中所述的一般。
Rubinius的设计决定了其调试功能的强大,使得在运行时常规的Ruby核可以使用大量的VM基础结构和原数据。操作码和已加载Ruby核的解析树(ParseTree),以及堆栈踪迹(stacktrace)都是可访问的。内部追查的能力更强了,例如使用SendSites。 SendSites指出了消息传递到哪(“方法调用”),它还能链接到方法上。这样就可以获得在运行时中已加载代码的配置,但也起到了代码分析和覆盖工具的作用。每发一条信息,Sendsite的计数器就会增加;由于这个信息也能用于Ruby代码,所以写一个简单的代码分析工具或者至少是代码覆盖工具就只是几行代码的事。
GUI
现在Rubinius调试器的用户接口还是命令行界面,它可以管理断点、单步调试,也能查看正在运行的Ruby核的操作码或者它们的源文件。 sexp [method]是一个实用的命令,它返回[method]的AST的ParseTree符号表达式(s-expr,忽略参数的情况下把当前方法的AST表示为ParseTree符号表达式)。这是十分有用的信息,特别是对于那些使用元编程(metaprogramming)的代码——运行时所生成的代码显然不含源代码。能够看到那些生成的被加载的代码显然对于调试那些元编程的代码有帮助。另外,能够看到符号表达式也比试图去猜测生成的代码是干什么的更进了一步,也更加方便了——通过采用基于ParseTree的工具,比如Ruby2Ruby,它是一个接收符号表达式并格式化后返回给Ruby源代码的工具。
直到本文发布之日为止,Rubinius和调试器GUI的连接还不没有出现。不过,由于现在调试协议实现已经可以工作了,这个状况即将发生改变。从实现调试支持的速度来判断,对调试器GUI的支持也不远了(调试协议的实现是调试器实现中的一个简单部分)。一旦它支持了debug-commons或者DBGp 协议,采用这些协议的IDE就能够用于Rubinius了。
IronRuby
IronRuby生成的是MS IL代码,它目标是.NET平台。它使用DLR,这个系统收集各种语言的公共功能,比如表达式树等产生的MS IL。
调试后端
DLR生成 .NET MS IL,也生成MS IL调试信息。这意味着IronRuby既可以使用.NET调试工具,也可以使用Visual Studio调试器的GUI。
GUI
你可以使用Visual Studio,而Ruby的SapphireSteel Ruby in Steel IDE——也是基于Visual Studio的IDE——也支持IronRuby开发。在以后的版本中肯定会增加调试功能。

热心网友 时间:2022-04-18 23:50

可以,直接在需要的地方插入

debugger

就可以了, 然后可以输入

continue

继续单步执行。

也可以尝试用pry gem, 然后用

binding.pry

使用next单步运行,step单步跟踪

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
立秋后钓鱼什么风向好-立秋钓鱼风向怎么选 赱乂砉込儬 怎么读 "赱"读什么? 解决电脑无法搜索到iPhone热点的问题如何修复iPhone热点无法在电脑上显... 电脑搜不到iphone12热点 iphone开热点给电脑搜不到 国企的地产有哪些 国企下设公司是什么意思? 红加蓝加绿是什么色. 梦幻西游75级开三倍抓鬼一轮有多少经验 重庆哪个区买房子好,自己住! 沙坪坝28中家属区怎么样?好不好?值不值得买? 重庆市沙坪坝区曾家镇那里以后会发展吗?现在在哪里买套房子以后会涨价吗? 重庆沙坪坝杨公桥龙凤云洲的房子怎么样?越详细越好。 请问重庆市沙坪坝区青木关那块儿的房子以后升值潜力大吗? 沙坪坝沙正街友谊村怎么样?好不好?值不值得买? 在沙坪坝上班,打算在大学城买房子,大家觉得大学城怎么样? 沙坪坝区青木关镇基本上全是小产权房,请问这种房子能买吗? 重庆沙坪坝区买房子上户口问题``急!~ 我在重庆市沙坪坝买的房子请问过户需要些什么材料 打算买新房,在重庆沙坪坝杨公桥/烈士墓附近和南岸茶园中心区相比较,哪个比较好,请帮忙分析理由? 沙坪坝买房交多少契税 平安鑫盛终身险分红型二十年之后能取钱么 能取多少 oppo微信设置了试用时间怎么操作 看完了整本ruby编程学习书好失望~我还写不出一个网站,一个带有界面的小工具……为什么还停留在黑框 微信使用时间越久越好吗 怎么看QQ被封了多少天 如何利用K线三角形的形态来判断和预测后市 三角形整理K线高点有好几个上影线该怎么画线?指的是上面的线该怎么画好? K线图不同三角形态对应不同的做单策略是什么? 泡沫密封胶弄到铝合金上了,怎样去除 泡沫填缝剂(泡沫胶)粘在铝合金上了怎么弄掉?? ps4战车世界怎么切换中文 战车世界亚服黑市一年几次 坦克世界闪电战与战车世界还有坦克世界电脑版什么关系 ps4战车世界怎么提示没eula 战车世界怎么让轻机枪自动攻击敌人 Ps4的战车世界 也就是坦克世界!有没有自动瞄准的设定!看清楚是ps4不是电脑? “坦克世界”的每个系分别是哪个国家的? 《方舟生存进化》琥珀怎么快速获得 琥珀获取途 《坦克世界》是哪家公司出品的游戏 周公解梦熊熊大火在井口 梦见大火买彩票买什么号 为什么游戏《坦克世界》就是不火? 给文件夹里的文件创建EXCEL索引 坦克世界车种简称 坦克世界怎么快速升级??? 坦克世界中各种战车定位是什么 坦克世界各系都什么车好用? 坦克世界各种坦克各系的选择