Version: trunk r13331 (Linux x86_64). Component: interpreter (Activity), native API.
When native code lets a SYNTAX condition reach its Rexx caller (a routine or method that calls Rexx code through CallRoutine and returns with the condition pending, or one that raises a condition object with RaiseConditionObject), the condition object can be garbage collected while it propagates. Seen as a SIGSEGV in HashContents::put <- RexxActivation::trap <- Activity::raisePropagate <- NativeActivation::run, now and then, in a multithreaded program (16 threads raising and trapping such conditions while others force collections; 3 runs out of 40).
Cause: NativeActivation::run() (and callNativeRoutine()) calls checkConditions(), which calls Activity::reraiseException() with the condition object the native activation holds, then raisePropagate(). raisePropagate() pops the native activation first (cleanupStackFrame() -> setHasNoReferences(): it no longer marks the object), then calls the Rexx caller's trap(), which allocates before it stores the object. A collection there takes it. RaiseException is not affected, because raiseException() keeps its object in the activity's conditionobj, which Activity::live() marks; a non-SYNTAX condition is not affected either (checkConditions() calls trap() while the native activation is still on the stack).
Fix (1 line): conditionobj = exobj; at the start of reraiseException(), as raiseException() does.
How it was checked: the window is too small for a deterministic test in the suite. With an instrumented build (a forced collection, plus reuse of the freed memory, at the start of RexxActivation::trap()), on r13331: RaiseConditionObject of a kept SYNTAX condition, and CallRoutine of Rexx code that raises SYNTAX left pending, both crash (SIGSEGV) without the fix and work with it; RaiseException and RaiseConditionObject of a USER condition work either way. With the plain fix: METHOD.testGroup 350/350, full test suite with no differences. Patch attached.
Anonymous