ADDITIONAL SYSTEM INFORMATION :
Tested on Java 11 and 21 on macOS 12.6.9
A DESCRIPTION OF THE PROBLEM :
When a stack overflow occurs while a lock is held, under JEP-270 the reserved stack should allow the lock state to be recovered and restored to be unlocked by the finally block. However, this appears to fail on the first few invocations and then succeed which indicates a different behavior during the warmup period.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Acquire a lock
2. Trigger a stack overflow in a try block
3. Release the lock in the finally block
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The lock is always left in an unlocked state.
ACTUAL -
The first execution it (usually) fails, after repeated executions it succeeds. Once successful it never fails again.
---------- BEGIN SOURCE ----------
import java.util.concurrent.locks.ReentrantLock;
public class OverflowTest {
public static void recurse() {
var lock = new ReentrantLock();
var recurser = new Runnable[1];
recurser[0] = () -> {
lock.lock();
try {
recurser[0].run();
} finally {
lock.unlock();
}
};
try {
recurser[0].run();
throw new AssertionError();
} catch (StackOverflowError expected) {}
if (lock.isLocked()) {
System.err.println("Lock");
} else {
System.out.println("Unlocked");
}
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
recurse();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Restart the jvm, the application is in a corrupted state
FREQUENCY : often