truffleruby
truffleruby copied to clipboard
Exception expanding the "Globals" section in the VS Code debugger
I'm trying to debug a Rails application. I'm using the following launch configuration:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "graalvm",
"request": "launch",
"name": "Launch Ruby Script",
"runtimeExecutable": "ruby",
"program": "${workspaceFolder}/bin/rails",
"args": ["server", "-p", "7089"],
"console": "integratedTerminal",
"cwd": "${workspaceFolder}",
"outputCapture": "std",
"protocol": "debugAdapter",
},
]
}
I set a breakpoint in ApplicationController on a include line. It looks something like:
# frozen_string_literal: true
class ApplicationController < ActionController::Base
include Authentication
...
end
While paused at the breakpoint on the include Authentication line, I expanded the "Globals" section in the "Variables" view. There's two sections labeled "Globals". I expanded the top-most one, which prints Ruby global variables. When I expanded it, the debugger/application crashed with:
truffleruby: an internal exception escaped out of the interpreter,
please report it to https://github.com/oracle/truffleruby/issues.
No such file or directory - -p (Errno::ENOENT) (com.oracle.truffle.api.debug.DebugException)
from <ruby>.Kernel#raise(resource:/truffleruby/core/kernel.rb:692)
from <ruby>.Errno.handle(resource:/truffleruby/core/errno.rb:48)
from <ruby>.IO.sysopen(resource:/truffleruby/core/io.rb:889)
from <ruby>.File#initialize(resource:/truffleruby/core/file.rb:1216)
from <ruby>.IO.open(resource:/truffleruby/core/io.rb:665)
from <ruby>.Truffle::ARGFClass#stream(resource:/truffleruby/core/argf.rb:550)
from <ruby>.Truffle::ARGFClass#advance!(resource:/truffleruby/core/argf.rb:613)
from <ruby>.Truffle::ARGFClass#filename(resource:/truffleruby/core/argf.rb:231)
from <ruby>.block in <top (required)>(resource:/truffleruby/core/argf.rb:636)
from <ruby>.<top (required)>((eval):1)
from <ruby>.Binding#eval(resource:/truffleruby/core/binding.rb:13)
from <ruby>.<class:ApplicationController>(Unknown:-1)
from <ruby>.<top (required)>(application_controller.rb:2)
from <ruby>.Kernel#gem_original_require(resource:/truffleruby/core/kernel.rb:234)
from <ruby>.Kernel#require(kernel.rb:27)
from <ruby>.<module:InheritedResources>(base.rb:11)
from <ruby>.<top (required)>(base.rb:1)
from <ruby>.Kernel#gem_original_require(resource:/truffleruby/core/kernel.rb:234)
from <ruby>.Kernel#require(kernel.rb:27)
from <ruby>.<module:ActiveAdmin>(authorization.rb:3)
from <ruby>.<top (required)>(authorization.rb:2)
from <ruby>.Kernel#gem_original_require(resource:/truffleruby/core/kernel.rb:234)
from <ruby>.Kernel#require(kernel.rb:35)
from <ruby>.<top (required)>(base_controller.rb:2)
from <ruby>.Kernel#gem_original_require(resource:/truffleruby/core/kernel.rb:234)
from <ruby>.Kernel#require(kernel.rb:35)
from <ruby>.<module:ActiveAdmin>(action_builder.rb:3)
from <ruby>.<top (required)>(action_builder.rb:2)
from <ruby>.Kernel#gem_original_require(resource:/truffleruby/core/kernel.rb:234)
from <ruby>.Kernel#require(kernel.rb:35)
from <ruby>.<top (required)>(resource_controller.rb:3)
from <ruby>.Kernel#gem_original_require(resource:/truffleruby/core/kernel.rb:234)
from <ruby>.Kernel#require(kernel.rb:35)
from <ruby>.block in <top (required)>(batch_actions.rb:8)
from <ruby>.block in ActiveAdmin.wrap_block_for_active_support_notifications(active_admin.rb:116)
from <ruby>.ActiveSupport::Notifications::Fanout::Subscribers::Timed#finish(fanout.rb:236)
from <ruby>.block in ActiveSupport::Notifications::Fanout#finish(fanout.rb:76)
from <ruby>.block in ActiveSupport::Notifications::Fanout#iterate_guarding_exceptions(fanout.rb:91)
from <ruby>.Array#each((core):1)
from <ruby>.ActiveSupport::Notifications::Fanout#iterate_guarding_exceptions(fanout.rb:90)
from <ruby>.ActiveSupport::Notifications::Fanout#finish(fanout.rb:76)
from <ruby>.ActiveSupport::Notifications::Instrumenter#finish_with_state(instrumenter.rb:49)
from <ruby>.ActiveSupport::Notifications::Instrumenter#instrument(instrumenter.rb:30)
from <ruby>.ActiveSupport::Notifications.instrument(notifications.rb:206)
from <ruby>.ActiveAdmin::Application#load!(application.rb:115)
from <ruby>.ActiveAdmin::Application#routes(application.rb:142)
from <ruby>.#<Class:ActiveAdmin>#routes(/home/spin/.bundle/yo/gems/activeadmin-2.13.1/lib/active_admin.rb:1)
from <ruby>.block in <top (required)>(routes.rb:205)
from <ruby>.BasicObject#instance_exec((core):1)
from <ruby>.ActionDispatch::Routing::RouteSet#eval_block(route_set.rb:428)
from <ruby>.ActionDispatch::Routing::RouteSet#draw(route_set.rb:410)
from <ruby>.<top (required)>(routes.rb:4)
from <ruby>.Truffle::KernelOperations.load((core):1)
from <ruby>.Kernel#load(resource:/truffleruby/core/kernel.rb:376)
from <ruby>.block in Rails::Application::RoutesReloader#load_paths(routes_reloader.rb:50)
from <ruby>.Array#each((core):1)
from <ruby>.Rails::Application::RoutesReloader#load_paths(routes_reloader.rb:50)
from <ruby>.Rails::Application::RoutesReloader#reload!(routes_reloader.rb:24)
from <ruby>.block in Rails::Application::RoutesReloader#updater(routes_reloader.rb:38)
from <ruby>.ActiveSupport::FileUpdateChecker#execute(file_update_checker.rb:83)
from <ruby>.Rails::Application::RoutesReloader#execute(/home/spin/.bundle/yo/gems/railties-7.0.3.1/lib/rails/application/routes_reloader.rb:1)
from <ruby>.block in <module:Finisher>(finisher.rb:158)
from <ruby>.BasicObject#instance_exec((core):1)
from <ruby>.Rails::Initializable::Initializer#run(initializable.rb:32)
from <ruby>.block in Rails::Initializable#run_initializers(initializable.rb:61)
from <ruby>.block in TSort.tsort_each(tsort.rb:228)
from <ruby>.block (2 levels) in TSort.each_strongly_connected_component(tsort.rb:350)
from <ruby>.TSort.each_strongly_connected_component_from(tsort.rb:431)
from <ruby>.block in TSort.each_strongly_connected_component(tsort.rb:349)
from <ruby>.Array#each((core):1)
from <ruby>.TSort.each_strongly_connected_component(tsort.rb:347)
from <ruby>.TSort.tsort_each(tsort.rb:226)
from <ruby>.TSort#tsort_each(tsort.rb:205)
from <ruby>.Rails::Initializable#run_initializers(initializable.rb:60)
from <ruby>.Rails::Application#initialize!(application.rb:372)
from <ruby>.<top (required)>(environment.rb:7)
from <ruby>.Kernel#require_relative(resource:/truffleruby/core/kernel.rb:293)
from <ruby>.<top (required)>(config.ru:3)
from <ruby>.Rack::Builder.new_from_string(builder.rb:116)
from <ruby>.Rack::Builder.load_file(builder.rb:105)
from <ruby>.Rack::Builder.parse_file(builder.rb:66)
from <ruby>.Rack::Server#build_app_and_options_from_config(server.rb:349)
from <ruby>.Rack::Server#app(server.rb:249)
from <ruby>.Rack::Server#wrapped_app(server.rb:422)
from <ruby>.Rails::Server#log_to_stdout(server_command.rb:76)
from <ruby>.Rails::Server#start(server_command.rb:36)
from <ruby>.block in Rails::Command::ServerCommand#perform(server_command.rb:143)
from <ruby>.Kernel#tap(resource:/truffleruby/core/kernel.rb:510)
from <ruby>.Rails::Command::ServerCommand#perform(server_command.rb:134)
from <ruby>.Thor::Command#run(command.rb:27)
from <ruby>.Thor::Invocation#invoke_command(invocation.rb:127)
from <ruby>.Thor.dispatch(thor.rb:392)
from <ruby>.Rails::Command::Base.perform(base.rb:87)
from <ruby>.Rails::Command.invoke(command.rb:48)
from <ruby>.<top (required)>(commands.rb:18)
from <ruby>.Kernel#gem_original_require(resource:/truffleruby/core/kernel.rb:234)
from <ruby>.<main>(rails:5)
from <ruby>.Truffle::Boot.main((core):1)
from <ruby>.block in <top (required)>(main_boot_source:1)
/home/spin/src/github.com/yo/yo/app/controllers/application_controller.rb:2:in `<class:ApplicationController>'
from /home/spin/src/github.com/yo/yo/app/controllers/application_controller.rb:2:in `<top (required)>'
from bin/rails:5:in `<main>'
... <truncate here>
The issue here is that $FILENAME is a preexisting global, which when read returns the same as ARGF.filename.
And that also fails on CRuby in such a case:
$ ruby -ve 'p $FILENAME' -- arg1 arg2
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-linux]
-e:1:in `<main>': No such file or directory @ rb_sysopen - arg1 (Errno::ENOENT)
I think InteropLibrary#hasMemberReadSideEffects() is exactly for this case, so we need to override it and return true for globals which have a getter Proc.