oracle / truffleruby

A high performance implementation of the Ruby programming language, built on GraalVM.
https://www.graalvm.org/ruby/
Other
2.99k stars 180 forks source link

dead handle during json test suite #3502

Closed eregon closed 3 months ago

eregon commented 3 months ago

https://github.com/flori/json/actions/runs/8378309248/job/22942585131?pr=574

$ rake test
...
JSONCommonInterfaceTest: 
  test_JSON:                        .: (0.010186)
  test_create_id:                   .: (0.002333)
  test_deep_const_get:                  .: (0.001815)
  test_dump:                        .: (0.045562)
  test_dump_should_modify_defaults:         .: (0.001352)
  test_fast_generate:                   .: (0.000880)
  test_generate:                    .: (0.000825)
  test_generator:                   .: (0.000742)
  test_index:                       .: (0.033440)
  test_load:                        .: (0.018457)
  test_load_file:                   .: (0.004928)
  test_load_file!:                  .: (0.003997)
  test_load_file_with_option:               .: (0.004694)
  test_load_file_with_option!:              .: (0.003341)
  test_load_null:                   .: (0.006252)

truffleruby: unexpected internal exception in at_exit,
please report it to https://github.com/oracle/truffleruby/issues

dead handle 0xbad000000038028 (com.oracle.truffle.api.CompilerDirectives.ShouldNotReachHere)
    from com.oracle.truffle.api.CompilerDirectives.shouldNotReachHere(CompilerDirectives.java:574)
    from com.oracle.truffle.api.CompilerDirectives.shouldNotReachHere(CompilerDirectives.java:520)
    from org.truffleruby.cext.UnwrapNode$UnwrapNativeNode.raiseError(UnwrapNode.java:107)
    from org.truffleruby.cext.UnwrapNode$UnwrapNativeNode.unwrapTaggedObject(UnwrapNode.java:92)
    from org.truffleruby.cext.UnwrapNodeGen$UnwrapNativeNodeGen$Inlined.execute(UnwrapNodeGen.java:377)
    from org.truffleruby.cext.UnwrapNode.longToWrapper(UnwrapNode.java:270)
    from org.truffleruby.cext.UnwrapNodeGen$Inlined.execute(UnwrapNodeGen.java:143)
    from org.truffleruby.cext.ValueWrapperManager$UnwrapperFunction.execute(ValueWrapperManager.java:401)
    from org.truffleruby.cext.UnwrapperFunctionGen$InteropLibraryExports$Cached.execute(UnwrapperFunctionGen.java:117)
    from com.oracle.truffle.llvm.runtime.nodes.func.LLVMDispatchNode$LLVMLookupDispatchForeignNode.doGeneric(LLVMDispatchNode.java:459)
    from com.oracle.truffle.llvm.runtime.nodes.func.LLVMDispatchNode$LLVMLookupDispatchForeignNode.doUnknownType(LLVMDispatchNode.java:487)
    from com.oracle.truffle.llvm.runtime.nodes.func.LLVMDispatchNodeGen$LLVMLookupDispatchForeignNodeGen.execute(LLVMDispatchNodeGen.java:1471)
    from com.oracle.truffle.llvm.runtime.nodes.func.LLVMDispatchNode.doForeignExecutable(LLVMDispatchNode.java:380)
    from com.oracle.truffle.llvm.runtime.nodes.func.LLVMDispatchNodeGen.executeDispatch(LLVMDispatchNodeGen.java:272)
    from com.oracle.truffle.llvm.runtime.nodes.func.LLVMCallNode.doCall(LLVMCallNode.java:82)
    from com.oracle.truffle.llvm.runtime.nodes.func.LLVMCallNodeGen.executeGeneric(LLVMCallNodeGen.java:37)
    from com.oracle.truffle.llvm.runtime.nodes.api.LLVMFrameNullerExpression.doGeneric(LLVMFrameNullerExpression.java:71)
    from com.oracle.truffle.llvm.runtime.nodes.api.LLVMFrameNullerExpressionNodeGen.executeGeneric(LLVMFrameNullerExpressionNodeGen.java:29)
    from com.oracle.truffle.llvm.runtime.nodes.intrinsics.interop.LLVMPolyglotInvoke.doInvoke(LLVMPolyglotInvoke.java:80)
    from com.oracle.truffle.llvm.runtime.nodes.intrinsics.interop.LLVMPolyglotInvoke.doIntrinsic(LLVMPolyglotInvoke.java:95)
    from com.oracle.truffle.llvm.runtime.nodes.intrinsics.interop.LLVMPolyglotInvokeNodeGen.executeGeneric(LLVMPolyglotInvokeNodeGen.java:78)
    from com.oracle.truffle.llvm.runtime.nodes.api.LLVMFrameNullerExpression.doGeneric(LLVMFrameNullerExpression.java:71)
    from com.oracle.truffle.llvm.runtime.nodes.api.LLVMFrameNullerExpressionNodeGen.executeGeneric(LLVMFrameNullerExpressionNodeGen.java:29)
    from com.oracle.truffle.llvm.runtime.nodes.func.LLVMCallNode.doCall(LLVMCallNode.java:79)
    from com.oracle.truffle.llvm.runtime.nodes.func.LLVMCallNodeGen.executeGeneric(LLVMCallNodeGen.java:37)
    from com.oracle.truffle.llvm.runtime.nodes.api.LLVMFrameNullerExpression.doGeneric(LLVMFrameNullerExpression.java:71)
    from com.oracle.truffle.llvm.runtime.nodes.api.LLVMFrameNullerExpressionNodeGen.executeGeneric(LLVMFrameNullerExpressionNodeGen.java:29)
    from com.oracle.truffle.llvm.runtime.nodes.vars.LLVMWriteNodeFactory$LLVMWriteI64NodeGen.execute_generic1(LLVMWriteNodeFactory.java:605)
    from com.oracle.truffle.llvm.runtime.nodes.vars.LLVMWriteNodeFactory$LLVMWriteI64NodeGen.execute(LLVMWriteNodeFactory.java:579)
    from com.oracle.truffle.llvm.runtime.nodes.base.LLVMBasicBlockNode$InitializedBlockNode.execute(LLVMBasicBlockNode.java:154)
    from com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNode.dispatchFromBasicBlock(LLVMDispatchBasicBlockNode.java:116)
    from com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNode.doDispatch(LLVMDispatchBasicBlockNode.java:87)
    from com.oracle.truffle.llvm.runtime.nodes.control.LLVMDispatchBasicBlockNodeGen.executeGeneric(LLVMDispatchBasicBlockNodeGen.java:33)
    from com.oracle.truffle.llvm.runtime.nodes.control.LLVMFunctionRootNode.doRun(LLVMFunctionRootNode.java:81)
    from com.oracle.truffle.llvm.runtime.nodes.control.LLVMFunctionRootNodeGen.executeGeneric(LLVMFunctionRootNodeGen.java:34)
    from com.oracle.truffle.llvm.runtime.nodes.func.LLVMFunctionStartNode.execute(LLVMFunctionStartNode.java:102)
/home/runner/.rubies/truffleruby-24.0.0/lib/truffle/truffle/cext_ruby.rb:40:in `parse'
    from /home/runner/work/json/json/lib/json/common.rb:219:in `parse'
    from /home/runner/work/json/json/lib/json/common.rb:552:in `load'
    from /home/runner/work/json/json/tests/json_common_interface_test.rb:91:in `test_load_with_options'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/testcase.rb:871:in `run_test'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/testcase.rb:566:in `block (2 levels) in run'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/fixture.rb:276:in `block in create_fixtures_runner'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/fixture.rb:276:in `block in create_fixtures_runner'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/fixture.rb:257:in `run_fixture'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/fixture.rb:292:in `run_setup'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/testcase.rb:564:in `block in run'
    from <internal:core> core/throw_catch.rb:36:in `catch'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/testcase.rb:563:in `run'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/testsuite.rb:124:in `run_test'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/testsuite.rb:53:in `run'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/testsuite.rb:124:in `run_test'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/testsuite.rb:53:in `run'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/ui/testrunnermediator.rb:67:in `run_suite'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/ui/testrunnermediator.rb:45:in `block (2 levels) in run'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/ui/testrunnermediator.rb:102:in `with_listener'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/ui/testrunnermediator.rb:41:in `block in run'
    from <internal:core> core/throw_catch.rb:36:in `catch'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/ui/testrunnermediator.rb:39:in `run'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/ui/testrunner.rb:40:in `start_mediator'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/ui/testrunner.rb:25:in `start'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/ui/testrunnerutilities.rb:24:in `run'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/autorunner.rb:469:in `block in run'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/autorunner.rb:525:in `change_work_directory'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/autorunner.rb:468:in `run'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit/autorunner.rb:66:in `run'
    from /home/runner/.rubies/truffleruby-24.0.0/lib/gems/gems/test-unit-3.6.2/lib/test/unit.rb:518:in `block (2 levels) in <top (required)>'

Reported by hsbt in https://github.com/flori/json/pull/575#issuecomment-2014156935.

eregon commented 3 months ago

I investigated this with @andrykonchin, it looks very similar to https://github.com/oracle/truffleruby/issues/3478#issuecomment-2015315471, except it's rb_gc_register_mark_object() instead of rb_global_variable(). rb_gc_register_mark_object() currently keeps alive the object/value, and not the ValueWrapper as it should and needed for Float & non-fixnum-long.

The JSON gem does:

void Init_parser(void)
{
    ...
    CNaN = rb_const_get(mJSON, rb_intern("NaN"));
    rb_gc_register_mark_object(CNaN);

The failing test is:

  def test_load_with_options
    json  = '{ "foo": NaN }'
    assert JSON.load(json, nil, :allow_nan => true)['foo'].nan?
  end
eregon commented 3 months ago

Fixed in a88a02b56d55dd2e5dc593f6df3c24988fc8f76a