JDK-8319309 : Lock not released after stack overflow
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 21.0.1
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: os_x
  • CPU: x86_64
  • Submitted: 2023-10-22
  • Updated: 2023-11-03
  • Resolved: 2023-11-03
Related Reports
Duplicate :  
Description
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



Comments
This is the same issue reported in JDK-8318888 - closing as a duplicate.
03-11-2023

Issue is reproduced. 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. OS: MacOS 13.3.1 JDK 11.0.21:Fail JDK 17.0.9:Fail JDK 21.0.1: Fail Output: java OverflowTest Java HotSpot(TM) 64-Bit Server VM warning: Potentially dangerous stack overflow in ReservedStackAccess annotated method OverflowTest$$Lambda$1/0x0000000133000a08.run()V [1] Lock Java HotSpot(TM) 64-Bit Server VM warning: Potentially dangerous stack overflow in ReservedStackAccess annotated method OverflowTest$$Lambda$1/0x0000000133000a08.run()V [1] Lock Unlocked Java HotSpot(TM) 64-Bit Server VM warning: Potentially dangerous stack overflow in ReservedStackAccess annotated method OverflowTest.lambda$recurse$0(Ljava/util/concurrent/locks/ReentrantLock;[Ljava/lang/Runnable;)V [1] Lock Java HotSpot(TM) 64-Bit Server VM warning: Potentially dangerous stack overflow in ReservedStackAccess annotated method OverflowTest$$Lambda$1/0x0000000133000a08.run()V [1] Lock Unlocked Unlocked Unlocked Moving it to dev team for further analysis.
02-11-2023