Closed pebauer68 closed 2 years ago
I'm running into other problems with Ruby 3.0.0 that may or may not be related to this one. If the problem persists with gem 1.3.0, I'll work on a new release that specifically targets Ruby 3 in the near future.
I've confirmed that the latest version of Readapt works with Ruby 3. @PyvesB could this be an issue with the Eclipse plugin instead of the gem?
I would tend to say it's unlikely given that it's a Ruby exception. The Eclipse plugin is a thin Java wrapper that launches Readapt as an external process.
@castwide have you specifically tried evaluating an expression in VSCode's debug console with Ruby 3?
@PyvesB I went back to make sure. Confirmed working with Ruby 3.0.0 in VS Code on Windows 10 and CentOS 7.6.
Will investigate some more in the coming weeks.
I've had some time to circle back to this. I can reproduce the same error as described by @pebauer68. Here's what I've observed so far.
Using the following example Ruby script from the ruby-lang.org website and setting a breakpoint on the say['love'] = "*love*"
line (I now realise this is a somewhat cheesy example, but it'll do 😄):
# Output "I love Ruby"
say = "I love Ruby"
puts say
# Output "I *LOVE* RUBY"
say['love'] = "*love*"
puts say.upcase
# Output "I *love* Ruby"
# five times
5.times { puts say }
Here's the extract of messages between the debug adapter and the IDE:
Content-Length: 344
{"type":"response","request_seq":1,"success":true,"command":"initialize","body":{"supportsConfigurationDoneRequest":true,"exceptionBreakpointFilters":[{"filter":"raise","label":"Break on raised exceptions","description":"The debugger will break when an exception is raised, regardless of whether it is subsequently rescued.","default":false}]}}
Content-Length: 38
{"type":"event","event":"initialized"}
Content-Length: 79
{"type":"response","request_seq":2,"success":true,"command":"launch","body":{}}
Content-Length: 287
{"type":"response","request_seq":3,"success":true,"command":"setBreakpoints","body":{"breakpoints":[{"verified":true,"source":{"name":"hello-world.rb","path":"C:\\Users\\Pierre-Yves\\Documents\\runtime-EclipseApplication\\hello-world\\hello-world.rb"},"line":6}]}}
Content-Length: 90
{"type":"response","request_seq":4,"success":true,"command":"configurationDone","body":{}}
Content-Length: 158
{"type":"event","event":"process","body":{"name":"C:/Users/Pierre-Yves/Documents/runtime-EclipseApplication/hello-world/hello-world.rb"}}
Content-Length: 74
{"type":"event","event":"thread","body":{"reason":"started","threadId":1}}
Content-Length: 74
{"type":"event","event":"thread","body":{"reason":"started","threadId":1}}
Content-Length: 78
{"type":"event","event":"stopped","body":{"reason":"breakpoint","threadId":1}}
Content-Length: 87
{"type":"event","event":"output","body":{"output":"I love Ruby\n","category":"stdout"}}
Content-Length: 118
{"type":"response","request_seq":5,"success":true,"command":"threads","body":{"threads":[{"id":1,"name":"Thread 1"}]}}
Content-Length: 866
{"type":"response","request_seq":6,"success":true,"command":"stackTrace","body":{"stackFrames":[{"name":"say['love'] = \"*love*\"","source":{"name":"hello-world.rb","path":"C:/Users/Pierre-Yves/Documents/runtime-EclipseApplication/hello-world/hello-world.rb"},"id":340,"line":6,"column":0},{"name":"run { load @file }","source":{"name":"debugger.rb","path":"C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/readapt-1.4.3/lib/readapt/debugger.rb"},"id":360,"line":66,"column":0},{"name":"yield if block_given?","source":{"name":"debugger.rb","path":"C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/readapt-1.4.3/lib/readapt/debugger.rb"},"id":380,"line":80,"column":0},{"name":"run { load @file }","source":{"name":"debugger.rb","path":"C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/readapt-1.4.3/lib/readapt/debugger.rb"},"id":400,"line":66,"column":0}],"totalFrames":4}}
Content-Length: 207
{"type":"response","request_seq":7,"success":true,"command":"scopes","body":{"scopes":[{"name":"Local","variablesReference":340,"expensive":false},{"name":"Global","variablesReference":1,"expensive":true}]}}
Content-Length: 153
{"type":"response","request_seq":8,"success":true,"command":"evaluate","body":{"result":"[NoMethodError] private method `eval' called for nil:NilClass"}}
I circled back to this and did some deeper debugging.
According to the protocol messages I previously posted, the Readapt line of code that is throwing the error is the following: https://github.com/castwide/readapt/blob/dbc5ec193bb45c07c6eef4bfb0050116b0339fc2/lib/readapt/frame.rb#L13
Adding some debug statements to the following line of code shows that, unlike VS Code, the request from Eclipse does not contain a frameId
parameter:
https://github.com/castwide/readapt/blob/dbc5ec193bb45c07c6eef4bfb0050116b0339fc2/lib/readapt/message/evaluate.rb#L9
Indeed, looking at the code that generates the request on the Eclipse side, the frameId
is not being set:
https://github.com/eclipse/lsp4e/blob/607e86e697e49e4f1cb1969ecdf9009cbfa47df4/org.eclipse.lsp4e.debug/src/org/eclipse/lsp4e/debug/console/DSPStreamsProxy.java#L51
However, according to the protocol specification, Eclipse is technically allowed to do so:
/**
* Evaluate the expression in the scope of this stack frame. If not specified,
* the expression is evaluated in the global scope.
*/
frameId?: number;
Readapt is essentially treating an optional parameter as mandatory, which is a bug. I'll be submitting a fix shortly to evaluate in the global scope when no frameId
is specified. I'll also submit an improvement to Eclipse so that it sends the frameId
when possible.
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux] eclipse: Version: 2020-09 (4.17.0) Entering a valid ruby expression in the eclipse console during debugging gives the following error in the eclipse console: [NoMethodError] private method `eval' called for nil:NilClass Where is this error coming from ?
Exception
NoMethodError' at /.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/readapt-1.2.0/lib/readapt/frame.rb:13 - private method
eval' called for nil:NilClass