Skip to content

Exception from inner context is incorrectly wrapped, causing AssertionError and infinite cause chains #13453

@eregon

Description

@eregon

Describe GraalVM and your environment :

  • GraalVM version or commit id if built from source: [e.g. 19.3]
  • CE or EE: EE
  • JDK version: 25.0.2
  • OS and OS Version: Linux
  • Architecture: amd64

Have you verified this issue still happens when using the latest snapshot?

Yes, because the code still has the same missing logic.

Describe the issue

From truffleruby/truffleruby#4233

Exceptions from an inner/other context are wrapped in OtherContextException.
The bug is when the exception comes back to the context that created it it's not wrapped, it's still in a OtherContextException.
That both triggers Truffle assert's:

no need for foreign value if contexts match (java.lang.AssertionError)
	from com.oracle.truffle.polyglot.OtherContextGuestObject$OtherContextException.<init>(OtherContextGuestObject.java:342)
	from com.oracle.truffle.polyglot.OtherContextGuestObject.migrateException(OtherContextGuestObject.java:187)
	from com.oracle.truffle.polyglot.EngineAccessor$EngineImpl.evalBoundary(EngineAccessor.java:944)
	from com.oracle.truffle.polyglot.EngineAccessor$EngineImpl.evalInternalContext(EngineAccessor.java:920)
	from com.oracle.truffle.api.TruffleContext.evalPublic(TruffleContext.java:358)
	from org.truffleruby.interop.PolyglotNodes$InnerContextEvalNode.eval(PolyglotNodes.java:282)
	from org.truffleruby.interop.PolyglotNodes$InnerContextEvalNode.evalCached(PolyglotNodes.java:253)
	from org.truffleruby.interop.PolyglotNodesFactory$InnerContextEvalNodeFactory$InnerContextEvalNodeGen.executeAndSpecialize(PolyglotNodesFactory.java:1037)
	from org.truffleruby.interop.PolyglotNodesFactory$InnerContextEvalNodeFactory$InnerContextEvalNodeGen.execute(PolyglotNodesFactory.java:953)
	from org.truffleruby.language.control.SequenceNode.execute(SequenceNode.java:36)
	from org.truffleruby.language.RubyMethodRootNode.execute(RubyMethodRootNode.java:66)

and more subtle and messy problems like stack overflows due to infinite cause chains because these etra wrappers break identity (InteropLibrary#isIdentical).

Steps to reproduce the issue

  • Create an inner context
  • Pass a lambda to the inner context, the lambda should throw an exception of the outer context
  • Call that lamba in the inner context
  • Catch the exception in the outer context, the exception object must be the initial outer exception, but it's not, that's the bug

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions