Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullPointerException in FrameUtil.getObjectSafe escaping from Interpreter #2156

Closed
petenorth opened this issue Nov 14, 2020 · 20 comments
Closed
Assignees
Milestone

Comments

@petenorth
Copy link

petenorth commented Nov 14, 2020

I've started seeing the following exceptions when running Cucumber tests

https://github.com/petenorth/schools-experience/runs/1399517944?check_suite_focus=true#step:8:90

  Background:              # features/candidates/bookings/cancelling_a_booking.feature:6
    Given I have a booking # features/step_definitions/candidates/bookings/cancelling_a_booking_steps.rb:1
truffleruby: an exception escaped out of the interpreter - this is an implementation bug
org.graalvm.polyglot.PolyglotException: java.lang.NullPointerException
	at com.oracle.truffle.api.frame.FrameUtil.getObjectSafe(FrameUtil.java:59)
	at org.truffleruby.core.kernel.TruffleKernelNodes$GetSpecialVariableStorage.getFromKnownFrameDescriptor(TruffleKernelNodes.java:248)
	at org.truffleruby.core.kernel.TruffleKernelNodesFactory$GetSpecialVariableStorageNodeGen.execute(TruffleKernelNodesFactory.java:615)
	at org.truffleruby.language.methods.BlockDefinitionNode.execute(BlockDefinitionNode.java:97)
	at org.truffleruby.language.methods.BlockDefinitionNode.execute(BlockDefinitionNode.java:30)
	at org.truffleruby.core.cast.ProcOrNullNodeGen.executeProcOrNull(ProcOrNullNodeGen.java:51)
	at org.truffleruby.language.dispatch.RubyCallNode.executeBlock(RubyCallNode.java:131)
	at org.truffleruby.language.dispatch.RubyCallNode.execute(RubyCallNode.java:100)
	at org.truffleruby.language.control.FrameOnStackNode.execute(FrameOnStackNode.java:37)
	at org.truffleruby.language.methods.CatchBreakNode.execute(CatchBreakNode.java:40)
	at org.truffleruby.language.control.SequenceNode.execute(SequenceNode.java:36)
	at org.truffleruby.language.arguments.CheckArityNode.execute(CheckArityNode.java:41)
	at org.truffleruby.language.control.SequenceNode.execute(SequenceNode.java:36)
	at org.truffleruby.language.methods.CatchForMethodNode.execute(CatchForMethodNode.java:42)
	at org.truffleruby.language.methods.ExceptionTranslatingNode.execute(ExceptionTranslatingNode.java:33)
	at org.truffleruby.language.RubyRootNode.execute(RubyRootNode.java:63)
	at <ruby> Selenium::WebDriver::Remote::W3C::Capabilities#camel_case(Unknown)
	at <ruby> block in Selenium::WebDriver::Remote::W3C::Capabilities#as_json(../truffleruby-head/lib/gems/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/w3c/capabilities.rb:275:10127-10176)
	at <ruby> Selenium::WebDriver::Remote::W3C::Capabilities#as_json(../truffleruby-head/lib/gems/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/w3c/capabilities.rb:262:9539-9584)
	at <ruby> Selenium::WebDriver::Remote::W3C::Capabilities#to_json(../truffleruby-head/lib/gems/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/w3c/capabilities.rb:285:10402-10434)
	at <ruby> block in JSON::Pure::Generator::GeneratorMethods::Array#json_transform(../truffleruby-head/lib/json/lib/json/pure/generator.rb:349:11732-11777)
	at <ruby> JSON::Pure::Generator::GeneratorMethods::Array#json_transform(../truffleruby-head/lib/json/lib/json/pure/generator.rb:345:11562-11587)
	at <ruby> JSON::Pure::Generator::GeneratorMethods::Array#to_json(../truffleruby-head/lib/json/lib/json/pure/generator.rb:332:11230-11262)
	at <ruby> ActiveSupport::ToJsonWithActiveSupportEncoder#to_json(../truffleruby-head/lib/gems/gems/activesupport-5.2.4.1/lib/active_support/core_ext/object/json.rb:38:1957-1978)
	at <ruby> block in JSON::Pure::Generator::GeneratorMethods::Hash#json_transform(../truffleruby-head/lib/json/lib/json/pure/generator.rb:310:10470-10515)
	at <ruby> JSON::Pure::Generator::GeneratorMethods::Hash#json_transform(../truffleruby-head/lib/json/lib/json/pure/generator.rb:302:10141-10170)
	at <ruby> JSON::Pure::Generator::GeneratorMethods::Hash#to_json(../truffleruby-head/lib/json/lib/json/pure/generator.rb:284:9672-9704)
	at <ruby> ActiveSupport::ToJsonWithActiveSupportEncoder#to_json(../truffleruby-head/lib/gems/gems/activesupport-5.2.4.1/lib/active_support/core_ext/object/json.rb:38:1957-1978)
	at <ruby> block in JSON::Pure::Generator::GeneratorMethods::Hash#json_transform(../truffleruby-head/lib/json/lib/json/pure/generator.rb:310:10470-10515)
	at <ruby> JSON::Pure::Generator::GeneratorMethods::Hash#json_transform(../truffleruby-head/lib/json/lib/json/pure/generator.rb:302:10141-10170)
	at <ruby> JSON::Pure::Generator::GeneratorMethods::Hash#to_json(../truffleruby-head/lib/json/lib/json/pure/generator.rb:284:9672-9704)
	at <ruby> ActiveSupport::ToJsonWithActiveSupportEncoder#to_json(../truffleruby-head/lib/gems/gems/activesupport-5.2.4.1/lib/active_support/core_ext/object/json.rb:38:1957-1978)
	at <ruby> JSON::Pure::Generator::State#generate(../truffleruby-head/lib/json/lib/json/pure/generator.rb:242:8156-8191)
	at <ruby> JSON#generate(../truffleruby-head/lib/json/lib/json/common.rb:224:8264-8286)
	at <ruby> Selenium::WebDriver::Remote::Http::Common#call(../truffleruby-head/lib/gems/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/http/common.rb:54:1797-1865)
	at <ruby> Selenium::WebDriver::Remote::Bridge#execute(../truffleruby-head/lib/gems/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/bridge.rb:167:5572-5616)
	at <ruby> Selenium::WebDriver::Remote::Bridge#create_session(../truffleruby-head/lib/gems/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/bridge.rb:102:3559-3656)
	at <ruby> Selenium::WebDriver::Remote::Bridge.handshake(../truffleruby-head/lib/gems/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/bridge.rb:56:1913-2003)
	at <ruby> Selenium::WebDriver::Remote::Driver#initialize(../truffleruby-head/lib/gems/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/driver.rb:39:1364-1405)
	at <ruby> Selenium::WebDriver::Driver.for(../truffleruby-head/lib/gems/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/common/driver.rb:58:1683-1718)
	at <ruby> Selenium::WebDriver.for(../truffleruby-head/lib/gems/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver.rb:88:3260-3293)
	at <ruby> Capybara::Selenium::Driver#browser(../truffleruby-head/lib/gems/gems/capybara-3.31.0/lib/capybara/selenium/driver.rb:51:1739-1816)
	at <ruby> Capybara::Selenium::Driver#visit(../truffleruby-head/lib/gems/gems/capybara-3.31.0/lib/capybara/selenium/driver.rb:70:2198-2226)
	at <ruby> Capybara::Session#visit(../truffleruby-head/lib/gems/gems/capybara-3.31.0/lib/capybara/session.rb:278:9966-9999)
	at <ruby> Capybara::DSL#visit(/truffleruby-head/lib/gems/gems/capybara-3.31.0/lib/capybara/dsl.rb:2:15-46)
	at <ruby> block in Object#<top (required)>(features/step_definitions/candidates/bookings/cancelling_a_booking_steps.rb:7:239-284)
	at <ruby> block in Cucumber::Glue::InvokeInWorld.cucumber_instance_exec_in(../truffleruby-head/lib/gems/gems/cucumber-3.1.2/lib/cucumber/glue/invoke_in_world.rb:39:1567-1612)
	at <ruby> Cucumber::Glue::InvokeInWorld.cucumber_run_with_backtrace_filtering(../truffleruby-head/lib/gems/gems/cucumber-3.1.2/lib/cucumber/glue/invoke_in_world.rb:54:1964-1978)
	at <ruby> Cucumber::Glue::InvokeInWorld.cucumber_instance_exec_in(../truffleruby-head/lib/gems/gems/cucumber-3.1.2/lib/cucumber/glue/invoke_in_world.rb:27:1019-1081)
	at <ruby> Cucumber::Glue::StepDefinition#invoke(../truffleruby-head/lib/gems/gems/cucumber-3.1.2/lib/cucumber/glue/step_definition.rb:110:3363-3475)
	at <ruby> Cucumber::StepMatch#invoke(../truffleruby-head/lib/gems/gems/cucumber-3.1.2/lib/cucumber/step_match.rb:31:954-992)
	at <ruby> block in Cucumber::StepMatch#activate(../truffleruby-head/lib/gems/gems/cucumber-3.1.2/lib/cucumber/step_match.rb:24:751-830)
	at <ruby> Cucumber::Core::Test::Action#execute(../truffleruby-head/lib/gems/gems/cucumber-core-3.2.1/lib/cucumber/core/test/action.rb:24:639-666)
	at <ruby> Cucumber::Core::Test::Step#execute(../truffleruby-head/lib/gems/gems/cucumber-core-3.2.1/lib/cucumber/core/test/step.rb:32:756-787)
	at <ruby> Cucumber::Core::Test::Runner::RunningTestCase::Status::Base#execute(../truffleruby-head/lib/gems/gems/cucumber-core-3.2.1/lib/cucumber/core/test/runner.rb:104:2734-2802)
	at <ruby> Cucumber::Core::Test::Runner::RunningTestCase#execute(../truffleruby-head/lib/gems/gems/cucumber-core-3.2.1/lib/cucumber/core/test/runner.rb:51:1480-1533)
	at <ruby> Cucumber::Core::Test::Runner#test_step(../truffleruby-head/lib/gems/gems/cucumber-core-3.2.1/lib/cucumber/core/test/runner.rb:27:783-842)
	at <ruby> Cucumber::Core::Test::Step#describe_to(../truffleruby-head/lib/gems/gems/cucumber-core-3.2.1/lib/cucumber/core/test/step.rb:17:434-473)
	at <ruby> block (3 levels) in Cucumber::Core::Test::Case#describe_to(../truffleruby-head/lib/gems/gems/cucumber-core-3.2.1/lib/cucumber/core/test/case.rb:28:878-936)
	at <ruby> block (2 levels) in Cucumber::Core::Test::Case#describe_to(../truffleruby-head/lib/gems/gems/cucumber-core-3.2.1/lib/cucumber/core/test/case.rb:27:833-876)
@eregon
Copy link
Member

eregon commented Nov 16, 2020

@aardvark179 Could you take a look at this one?

@petenorth
Copy link
Author

Hopefully the following is a simpler project with a GitHub workflow which shows the difference in behaviour between HEAD, 20.2 and MRI (the latter two behave in the same way).

https://github.com/petenorth/gsub-tests/runs/1409321836?check_suite_focus=true

The matrix provided to the workflow is made up of [2.6, truffleruby, truffleruby-head] these correspond to MRI, 20.2 and HEAD respectively.

MRI and 20.2 fail but in an expected way, HEAD fails but due to a null pointer escaping from the interpreter.

I'd like to create a simpler reproducer but this is the best i can do at the moment. It seems to be due to the passing of some ruby symbol to camel case in Selenium::WebDriver::Remote::W3C::Capabilities#camel_case

Whose method body is str.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }

@chrisseaton
Copy link
Collaborator

I've seen these as well. Can't give you a reproducer right now I'm afraid.

@eregon
Copy link
Member

eregon commented Nov 17, 2020

@petenorth @chrisseaton Do you see this NullPointerException consistently or is it transient?

@aardvark179
Copy link
Contributor

I've not been able to reproduce this locally, so I'm not sure if it's a race or compilation bug. What I can do for now is improve the error reporting when this problem occurs which should help use narrow down where the problem is occurring in Ruby code, and whether we've made some assumption that is not actually valid.

@petenorth
Copy link
Author

I experience it consistently on every run.

@chrisseaton
Copy link
Collaborator

Sorry I can't remember where I've seen it, but I definitely recognise seeing it. Sorry that's not very helpful.

@eregon
Copy link
Member

eregon commented Nov 17, 2020

The -head builds are a bit old (5 days) due to some macOS/jt issue, will fix and then let's try again to repro with the newer builds.

@petenorth
Copy link
Author

petenorth commented Nov 17, 2020

git clone https://github.com/petenorth/gsub-tests.git
cd gsub-tests.git
gem install rails
rails new cucumber_bdd_how_to
mv Gemfile.example cucumber_bdd_how_to/Gemfile
cd cucumber_bdd_how_to
bundler install
rails generate cucumber:install
mv ../hello_world.feature features
mv ../hello_world_steps.rb features/step_definitions
mv ../env.rb features/support
rm .ruby-version 
RUBYOPT=--experimental-options\ --engine.Mode=latency
CUC_DRIVER=chrome APP_URL='http://en.wikipedia.org' SELENIUM_HUB_HOSTNAME=selenium-chrome bundle exec cucumber features/hello_world.feature

@eregon
Copy link
Member

eregon commented Nov 18, 2020

@petenorth There are new truffleruby-head builds now, could you trigger the gsub-tests workflow?
Most likely it still happens, but the backtrace should be a bit more understandable at least.

@petenorth
Copy link
Author

Here are the results of the latest run

https://github.com/petenorth/gsub-tests/runs/1418047935

@eregon
Copy link
Member

eregon commented Nov 18, 2020

I can reproduce it locally, thanks for the commands above, that was convenient.

@gogainda
Copy link
Contributor

gogainda commented Nov 18, 2020

I see the similar issue on every run:

git clone git@github.com:mbj/mutant.git   
cd mutant
bundle install
bundle exec rspec spec/unit

An exception:

<no message> (java.lang.NullPointerException)
	from com.oracle.truffle.api.frame.FrameUtil.getObjectSafe(FrameUtil.java:59)
	from org.truffleruby.core.kernel.TruffleKernelNodes$GetSpecialVariableStorage.getFromKnownFrameDescriptor(TruffleKernelNodes.java:250)
	from org.truffleruby.core.kernel.TruffleKernelNodesFactory$GetSpecialVariableStorageNodeGen.execute(TruffleKernelNodesFactory.java:621)
	from org.truffleruby.language.methods.BlockDefinitionNode.execute(BlockDefinitionNode.java:97)
	from org.truffleruby.language.methods.BlockDefinitionNode.execute(BlockDefinitionNode.java:30)
	from org.truffleruby.core.cast.ProcOrNullNodeGen.executeProcOrNull(ProcOrNullNodeGen.java:51)
	from org.truffleruby.language.dispatch.RubyCallNode.executeBlock(RubyCallNode.java:131)
	from org.truffleruby.language.dispatch.RubyCallNode.execute(RubyCallNode.java:100)
	from org.truffleruby.language.control.FrameOnStackNode.execute(FrameOnStackNode.java:37)
	from org.truffleruby.language.methods.CatchBreakNode.execute(CatchBreakNode.java:40)
	from org.truffleruby.language.control.SequenceNode.execute(SequenceNode.java:36)
	from org.truffleruby.language.arguments.CheckArityNode.execute(CheckArityNode.java:41)
	from org.truffleruby.language.control.SequenceNode.execute(SequenceNode.java:36)
	from org.truffleruby.language.methods.CatchForMethodNode.execute(CatchForMethodNode.java:42)
	from org.truffleruby.language.methods.ExceptionTranslatingNode.execute(ExceptionTranslatingNode.java:33)
	from org.truffleruby.language.RubyRootNode.execute(RubyRootNode.java:61)
	from org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.executeRootNode(OptimizedCallTarget.java:555)
/Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/unparser-0.5.4/lib/unparser/validation.rb:80:in `unparse_either'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/unparser-0.5.4/lib/unparser/validation.rb:80:in `from_node'
	from /Users/novoi/tmp/mutant/lib/mutant/meta/example/verification.rb:82:in `block in invalid'
	from <internal:core> core/enumerable.rb:140:in `block in each_with_object'
	from <internal:core> core/enumerable.rb:139:in `each'
	from <internal:core> core/enumerable.rb:139:in `each_with_object'
	from /Users/novoi/tmp/mutant/lib/mutant/meta/example/verification.rb:81:in `invalid'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:117:in `call'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:117:in `block (3 levels) in create_memoized_method'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/memory.rb:63:in `block (3 levels) in fetch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/thread_safe-0.3.6/lib/thread_safe/cache.rb:56:in `fetch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/memory.rb:62:in `block (2 levels) in fetch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/mri/monitor.rb:235:in `mon_synchronize'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/memory.rb:61:in `block in fetch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/thread_safe-0.3.6/lib/thread_safe/cache.rb:56:in `fetch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/memory.rb:60:in `fetch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:116:in `invalid'
	from /Users/novoi/tmp/mutant/lib/mutant/meta/example/verification.rb:16:in `success?'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:117:in `call'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:117:in `block (3 levels) in create_memoized_method'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/memory.rb:63:in `block (3 levels) in fetch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/thread_safe-0.3.6/lib/thread_safe/cache.rb:56:in `fetch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/memory.rb:62:in `block (2 levels) in fetch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/mri/monitor.rb:235:in `mon_synchronize'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/memory.rb:61:in `block in fetch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/thread_safe-0.3.6/lib/thread_safe/cache.rb:56:in `fetch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/memory.rb:60:in `fetch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:116:in `success?'
	from /Users/novoi/tmp/mutant/spec/unit/mutant/mutator/node_spec.rb:17:in `block (4 levels) in <top (required)>'
	from /Users/novoi/tmp/mutant/spec/unit/mutant/mutator/node_spec.rb:15:in `each'
	from /Users/novoi/tmp/mutant/spec/unit/mutant/mutator/node_spec.rb:15:in `block (3 levels) in <top (required)>'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:262:in `instance_exec'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:262:in `block in run'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:508:in `block in with_around_and_singleton_context_hooks'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:465:in `block in with_around_example_hooks'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/hooks.rb:486:in `block in run'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/hooks.rb:626:in `block in run_around_example_hooks_for'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:350:in `call'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:350:in `call'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:348:in `call'
	from /Users/novoi/.rubies/truffleruby-dev/lib/truffle/timeout.rb:163:in `timeout'
	from /Users/novoi/tmp/mutant/spec/spec_helper.rb:92:in `block in <top (required)>'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:455:in `instance_exec'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:455:in `instance_exec'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/hooks.rb:390:in `execute_with'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/hooks.rb:628:in `block (2 levels) in run_around_example_hooks_for'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:350:in `call'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:350:in `call'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/hooks.rb:627:in `run_around_example_hooks_for'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/hooks.rb:486:in `run'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:465:in `with_around_example_hooks'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:508:in `with_around_and_singleton_context_hooks'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example.rb:259:in `run'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example_group.rb:644:in `block in run_examples'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example_group.rb:640:in `map'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example_group.rb:640:in `run_examples'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/example_group.rb:606:in `run'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/runner.rb:121:in `block (3 levels) in run_specs'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/runner.rb:121:in `map'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/runner.rb:121:in `block (2 levels) in run_specs'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/configuration.rb:2067:in `with_suite_hooks'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/runner.rb:116:in `block in run_specs'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/reporter.rb:74:in `report'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/runner.rb:115:in `run_specs'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/runner.rb:89:in `run'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/runner.rb:71:in `run'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/lib/rspec/core/runner.rb:45:in `invoke'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/rspec-core-3.10.0/exe/rspec:4:in `<top (required)>'
	from <internal:core> core/kernel.rb:401:in `load'
	from <internal:core> core/kernel.rb:401:in `load'
	from /Users/novoi/.rubies/truffleruby-dev/bin/rspec:23:in `<top (required)>'
	from <internal:core> core/kernel.rb:401:in `load'
	from <internal:core> core/kernel.rb:401:in `load'
	from /Users/novoi/.rubies/truffleruby-dev/lib/mri/bundler/cli/exec.rb:63:in `kernel_load'
	from /Users/novoi/.rubies/truffleruby-dev/lib/mri/bundler/cli/exec.rb:28:in `run'
	from /Users/novoi/.rubies/truffleruby-dev/lib/mri/bundler/cli.rb:476:in `exec'
	from /Users/novoi/.rubies/truffleruby-dev/lib/mri/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
	from /Users/novoi/.rubies/truffleruby-dev/lib/mri/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
	from /Users/novoi/.rubies/truffleruby-dev/lib/mri/bundler/vendor/thor/lib/thor.rb:399:in `dispatch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/mri/bundler/cli.rb:30:in `dispatch'
	from /Users/novoi/.rubies/truffleruby-dev/lib/mri/bundler/vendor/thor/lib/thor/base.rb:476:in `start'
	from /Users/novoi/.rubies/truffleruby-dev/lib/mri/bundler/cli.rb:24:in `start'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/bundler-2.1.4/libexec/bundle:46:in `block in <top (required)>'
	from /Users/novoi/.rubies/truffleruby-dev/lib/mri/bundler/friendly_errors.rb:123:in `with_friendly_errors'
	from /Users/novoi/.rubies/truffleruby-dev/lib/gems/gems/bundler-2.1.4/libexec/bundle:34:in `<top (required)>'
	from <internal:core> core/kernel.rb:401:in `load'
	from <internal:core> core/kernel.rb:401:in `load'
	from /Users/novoi/.rubies/truffleruby-dev/bin/bundle:23:in `<main>'

@eregon
Copy link
Member

eregon commented Nov 19, 2020

Thanks, I could figure out what was going on with the mutant reproduction.
This is a minimal reproducer:

def bar
  yield
end

def foo
  bar { } # The block captures svars
end

method(:foo).to_proc.call
foo

For Method#to_proc we create a dummy declaration frame, and so we end up storing special variables there. But then on the normal call there is no declaration frame, and the node gets confused.

@aardvark179
Copy link
Contributor

I've talked this over with @eregon and we have a couple of potential ways to fix this. It looks like it has been a potentially long standing bug, but has been thrown into sharp relief by the changes to how we create and access storage for special variables. I'll prototype our potential fixes and add some specs so we can work out which pattern will work best and introduce the fewest additional complications.

@aardvark179
Copy link
Contributor

A fix for this has been merged in 1861a67. I'll leave this issue open for a little while to give you all time to check this is resolved once there is a new build of truffleruby-head.

@gogainda
Copy link
Contributor

For mutant gem I still see some issues, but not getObjectSafe, so I guess it works now. Waiting for @petenorth response

@petenorth
Copy link
Author

petenorth commented Nov 20, 2020

The cucumber tests are now running (i.e. the fix is working)! Thanks for the fixing this.

Will the fix be included in a 20.3 patch release?

@eregon
Copy link
Member

eregon commented Nov 23, 2020

We'll backport the fix to the 20.3 release branch, but it's not clear yet if there will be a release based on 20.3 before 21.0.0 comes out (est. 19 Jan 2021).

@petenorth
Copy link
Author

@aardvark179 I think this can be closed now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants