oracle / truffleruby

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

NullPointerException with --inspect, maybe failing to remove breakpoint #2827

Closed notEthan closed 1 year ago

notEthan commented 1 year ago

I encountered this error output running a ruby program with --inspect, but the ruby process continued with the chrome debugger attached. I think this happened when I was removing breakpoints in chrome (not entirely sure; I had hit 'resume' before I noticed the error output), and in this debug session, execution is stopping on a breakpoint I had clicked remove on, and which is not visible in chrome.

$ ruby --inspect test/scorpio_test.rb 
Debugger listening on ws://127.0.0.1:9229/iso76Uf9qks-z9Jnu-GlOerDqA6-NN9PCUchZ_WOsls
For help, see: https://www.graalvm.org/tools/chrome-debugger
E.g. in Chrome open: devtools://devtools/bundled/js_app.html?ws=127.0.0.1:9229/iso76Uf9qks-z9Jnu-GlOerDqA6-NN9PCUchZ_WOsls
java.lang.NullPointerException
  at org.truffleruby.core.array.ArrayGuards.storageStrategyLimit(ArrayGuards.java:18)
  at org.truffleruby.language.exceptions.RescueSplatNode.<init>(RescueSplatNode.java:39)
  at org.truffleruby.parser.BodyTranslator.translateRescueSplatParseNode(BodyTranslator.java:2833)
  ...

Full output (too large for github): https://pastebin.com/0E2vCTgW

eregon commented 1 year ago

Thank you for the report. The stacktrace is enough to find out the issue here:

$ ruby --inspect test/scorpio_test.rb 
Debugger listening on ws://127.0.0.1:9229/iso76Uf9qks-z9Jnu-GlOerDqA6-NN9PCUchZ_WOsls
For help, see: https://www.graalvm.org/tools/chrome-debugger
E.g. in Chrome open: devtools://devtools/bundled/js_app.html?ws=127.0.0.1:9229/iso76Uf9qks-z9Jnu-GlOerDqA6-NN9PCUchZ_WOsls
java.lang.NullPointerException
  at org.truffleruby.core.array.ArrayGuards.storageStrategyLimit(ArrayGuards.java:18)
  at org.truffleruby.language.exceptions.RescueSplatNode.<init>(RescueSplatNode.java:39)
  at org.truffleruby.parser.BodyTranslator.translateRescueSplatParseNode(BodyTranslator.java:2833)
  at org.truffleruby.parser.BodyTranslator.visitRescueNode(BodyTranslator.java:2773)
  at org.truffleruby.parser.BodyTranslator.visitRescueNode(BodyTranslator.java:280)
  at org.truffleruby.parser.ast.RescueParseNode.accept(RescueParseNode.java:67)
  at org.truffleruby.parser.Translator.translateNodeOrNil(Translator.java:129)
  at org.truffleruby.parser.MethodTranslator.compileBlockNode(MethodTranslator.java:137)
  at org.truffleruby.parser.BodyTranslator.translateBlockLikeNode(BodyTranslator.java:2048)
  at org.truffleruby.parser.BodyTranslator.visitIterNode(BodyTranslator.java:1979)
  at org.truffleruby.parser.BodyTranslator.visitIterNode(BodyTranslator.java:280)
  at org.truffleruby.parser.ast.IterParseNode.accept(IterParseNode.java:77)
  at org.truffleruby.parser.BodyTranslator.translateArgumentsAndBlock(BodyTranslator.java:734)
  at org.truffleruby.parser.BodyTranslator.translateCallNode(BodyTranslator.java:583)
  at org.truffleruby.parser.BodyTranslator.visitFCallNode(BodyTranslator.java:1587)
  at org.truffleruby.parser.BodyTranslator.visitFCallNode(BodyTranslator.java:280)
  at org.truffleruby.parser.ast.FCallParseNode.accept(FCallParseNode.java:68)
  at org.truffleruby.parser.Translator.translateNodeOrNil(Translator.java:129)
  at org.truffleruby.parser.BodyTranslator.visitBlockNode(BodyTranslator.java:478)
  at org.truffleruby.parser.BodyTranslator.visitBlockNode(BodyTranslator.java:280)
  at org.truffleruby.parser.ast.BlockParseNode.accept(BlockParseNode.java:55)
  at org.truffleruby.parser.Translator.translateNodeOrNil(Translator.java:129)
  at org.truffleruby.parser.BodyTranslator.visitRescueNode(BodyTranslator.java:2747)
  at org.truffleruby.parser.BodyTranslator.visitRescueNode(BodyTranslator.java:280)
  at org.truffleruby.parser.ast.RescueParseNode.accept(RescueParseNode.java:67)
  at org.truffleruby.parser.Translator.translateNodeOrNil(Translator.java:129)
  at org.truffleruby.parser.MethodTranslator.compileMethodBody(MethodTranslator.java:394)
  at org.truffleruby.parser.MethodTranslator.translateMethodNode(MethodTranslator.java:409)
  at org.truffleruby.parser.MethodTranslator.lambda$buildMethodNodeCompiler$2(MethodTranslator.java:426)
  at org.truffleruby.language.methods.CachedLazyCallTargetSupplier.get(CachedLazyCallTargetSupplier.java:37)
  at org.truffleruby.language.methods.LiteralMethodDefinitionNode.materializeInstrumentableNodes(LiteralMethodDefinitionNode.java:98)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$Visitor.materializeSyntaxNodes(InstrumentationHandler.java:1897)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$Visitor.materialize(InstrumentationHandler.java:1814)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$Visitor.visit(InstrumentationHandler.java:1775)
  at org.graalvm.truffle/com.oracle.truffle.api.nodes.NodeUtil.forEachChild(NodeUtil.java:486)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$Visitor.visit(InstrumentationHandler.java:1802)
  at org.graalvm.truffle/com.oracle.truffle.api.nodes.NodeUtil.forEachChild(NodeUtil.java:475)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$Visitor.visit(InstrumentationHandler.java:1802)
  at org.graalvm.truffle/com.oracle.truffle.api.nodes.NodeUtil.forEachChild(NodeUtil.java:486)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$Visitor.visit(InstrumentationHandler.java:1802)
  at org.graalvm.truffle/com.oracle.truffle.api.nodes.NodeUtil.forEachChild(NodeUtil.java:475)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$Visitor.visit(InstrumentationHandler.java:1802)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.visitRoot(InstrumentationHandler.java:1116)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.visitRoot(InstrumentationHandler.java:1081)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.visitRoots(InstrumentationHandler.java:550)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.visitLoadedSourceSections(InstrumentationHandler.java:392)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.visitLoadedSourceSections(InstrumentationHandler.java:881)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$AbstractInstrumenter.visitLoadedSourceSections(InstrumentationHandler.java:2394)
  at org.graalvm.truffle/com.oracle.truffle.api.debug.SuspendableLocationFinder.findNearestBound(SuspendableLocationFinder.java:117)
  at org.graalvm.truffle/com.oracle.truffle.api.debug.SuspendableLocationFinder.findNearest(SuspendableLocationFinder.java:95)
  at org.graalvm.truffle/com.oracle.truffle.api.debug.BreakpointLocation$BreakpointSourceLocation.adjustLocation(BreakpointLocation.java:241)
  at org.graalvm.truffle/com.oracle.truffle.api.debug.Breakpoint.resolveBreakpointAssignBinding(Breakpoint.java:591)
  at org.graalvm.truffle/com.oracle.truffle.api.debug.Breakpoint$1.onExecute(Breakpoint.java:563)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.notifySourceExecutedBinding(InstrumentationHandler.java:754)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.notifySourceExecutedBindings(InstrumentationHandler.java:747)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$2.accept(InstrumentationHandler.java:125)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$2.accept(InstrumentationHandler.java:122)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.SourceInstrumentationHandler$AllSourcesNotification.runNotifications(SourceInstrumentationHandler.java:407)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.SourceInstrumentationHandler$SourcesNotificationQueue.process(SourceInstrumentationHandler.java:312)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.addSourceExecutionBinding(InstrumentationHandler.java:434)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$AbstractInstrumenter.attachSourceExecutedBinding(InstrumentationHandler.java:2301)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.EventBinding$SourceExecuted.doAttach(EventBinding.java:211)
  at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.EventBinding.attach(EventBinding.java:144)
  at org.graalvm.truffle/com.oracle.truffle.api.debug.Breakpoint.install(Breakpoint.java:568)
  at org.graalvm.truffle/com.oracle.truffle.api.debug.Breakpoint.install(Breakpoint.java:548)
  at org.graalvm.truffle/com.oracle.truffle.api.debug.DebuggerSession.install(DebuggerSession.java:926)
  at org.graalvm.truffle/com.oracle.truffle.api.debug.DebuggerSession.install(DebuggerSession.java:908)
  at com.oracle.truffle.tools.chromeinspector.BreakpointsHandler.lambda$createURLBreakpoint$0(BreakpointsHandler.java:95)
  at com.oracle.truffle.tools.chromeinspector.ScriptsHandler.addLoadScriptListener(ScriptsHandler.java:95)
  at com.oracle.truffle.tools.chromeinspector.BreakpointsHandler.createURLBreakpoint(BreakpointsHandler.java:108)
  at com.oracle.truffle.tools.chromeinspector.InspectorDebugger.setBreakpointByUrl(InspectorDebugger.java:626)
  at com.oracle.truffle.tools.chromeinspector.server.InspectServerSession.doProcessCommand(InspectServerSession.java:459)
  at com.oracle.truffle.tools.chromeinspector.server.InspectServerSession.processCommand(InspectServerSession.java:300)
  at com.oracle.truffle.tools.chromeinspector.server.InspectServerSession$CommandProcessThread.run(InspectServerSession.java:651)
  at com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:775)
  at com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:203)

So during materializeInstrumentableNodes we are not always entered in a Context so we cannot use RubyLanguage.getCurrentLanguage(), instead we need to pass the RubyLanguage instance around.

eregon commented 1 year ago

The general fix in Truffle, so RubyLanguage.getCurrentLanguage() just works in that case, which should prevent further issues like this: https://github.com/oracle/graal/commit/d09dd204d5ce4dc23c34d52ff97709f01aa71b85