Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jdk24 java/lang/Thread/virtual/MonitorWaitNotify AssertionFailedError: expected: <true> but was: <false> #20369

Closed
pshipton opened this issue Oct 16, 2024 · 7 comments

Comments

@pshipton
Copy link
Member

pshipton commented Oct 16, 2024

https://openj9-jenkins.osuosl.org/job/Test_openjdknext_j9_sanity.openjdk_aarch64_mac_Personal_testList_0/7
jdk_lang_1
java/lang/Thread/virtual/MonitorWaitNotify.java

17:07:03  STARTED    MonitorWaitNotify::testInterruptWait '[1] 0'
17:07:03  Exception in thread "" org.opentest4j.AssertionFailedError: expected: <true> but was: <false>
17:07:03  	at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
17:07:03  	at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
17:07:03  	at org.junit.jupiter.api.AssertTrue.failNotTrue(AssertTrue.java:63)
17:07:03  	at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:36)
17:07:03  	at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:31)
17:07:03  	at org.junit.jupiter.api.Assertions.assertTrue(Assertions.java:183)
17:07:03  	at MonitorWaitNotify.lambda$testInterruptWait$0(MonitorWaitNotify.java:314)
17:07:03  	at java.base/java.lang.VirtualThread.run(VirtualThread.java:410)
17:07:03  org.opentest4j.AssertionFailedError: expected: <true> but was: <false>
17:07:03  	at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
17:07:03  	at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
17:07:03  	at org.junit.jupiter.api.AssertTrue.failNotTrue(AssertTrue.java:63)
17:07:03  	at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:36)
17:07:03  	at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:31)
17:07:03  	at org.junit.jupiter.api.Assertions.assertTrue(Assertions.java:183)
17:07:03  	at MonitorWaitNotify.testInterruptWait(MonitorWaitNotify.java:331)
17:07:03  	at java.base/java.lang.reflect.Method.invoke(Method.java:579)
17:07:03  	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:186)
17:07:03  	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:215)
17:07:03  	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:197)
17:07:03  	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:215)
17:07:03  	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:186)
17:07:03  	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:215)
17:07:03  	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:215)
17:07:03  	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:215)
17:07:03  	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:186)
17:07:03  	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:215)
17:07:03  	at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:1024)
17:07:03  	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:583)
17:07:03  	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:573)
17:07:03  	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:153)
17:07:03  	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:176)
17:07:03  	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:270)
17:07:03  	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:636)
17:07:03  	at java.base/java.util.stream.ReferencePipeline$7$1FlatMap.accept(ReferencePipeline.java:294)
17:07:03  	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:215)
17:07:03  	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:215)
17:07:03  	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:215)
17:07:03  	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1716)
17:07:03  	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:583)
17:07:03  	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:573)
17:07:03  	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:153)
17:07:03  	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:176)
17:07:03  	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:270)
17:07:03  	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:636)
17:07:03  	at java.base/java.util.stream.ReferencePipeline$7$1FlatMap.accept(ReferencePipeline.java:294)
17:07:03  	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1716)
17:07:03  	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:583)
17:07:03  	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:573)
17:07:03  	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:153)
17:07:03  	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:176)
17:07:03  	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:270)
17:07:03  	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:636)
17:07:03  	at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
17:07:03  	at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
17:07:03  FAILED     MonitorWaitNotify::testInterruptWait '[1] 0'
Copy link

Issue Number: 20369
Status: Open
Recommended Components: comp:vm, comp:jclextensions, comp:test
Recommended Assignees: pshipton, fengxue-is, babsingh

@pshipton
Copy link
Member Author

Excluding the tests via adoptium/aqa-tests#5889

java/lang/Thread/virtual/MonitorWaitNotify.java#default
java/lang/Thread/virtual/MonitorWaitNotify.java#LM_LEGACY
java/lang/Thread/virtual/MonitorWaitNotify.java#LM_LIGHTWEIGHT
java/lang/Thread/virtual/MonitorWaitNotify.java#Xcomp-LM_LEGACY
java/lang/Thread/virtual/MonitorWaitNotify.java#Xcomp-LM_LIGHTWEIGHT
java/lang/Thread/virtual/MonitorWaitNotify.java#Xcomp-noTieredCompilation-LM_LEGACY
java/lang/Thread/virtual/MonitorWaitNotify.java#Xcomp-noTieredCompilation-LM_LIGHTWEIGHT
java/lang/Thread/virtual/MonitorWaitNotify.java#Xcomp-TieredStopAtLevel1-LM_LEGACY
java/lang/Thread/virtual/MonitorWaitNotify.java#Xcomp-TieredStopAtLevel1-LM_LIGHTWEIGHT
java/lang/Thread/virtual/MonitorWaitNotify.java#Xint-LM_LEGACY
java/lang/Thread/virtual/MonitorWaitNotify.java#Xint-LM_LIGHTWEIGHT

@babsingh
Copy link
Contributor

@fengxue-IS Assigning it to you since it is related to Virtual Threads Pinning work.

@babsingh
Copy link
Contributor

babsingh commented Mar 11, 2025

  1. Instead of transitioning to TIMED_WAITING or WAITING for lock.wait(), the VirtualThread (VT) gets TERMINATED. There is an issue in VT's wait logic.
  2. InterruptedException is not thrown, when a VT, waiting on lock.wait, is sent an Thread.interrupt(). Interrupt logic needs to be fixed.
  3. If a thread is notified before wait, then objectMonitor->waitingContinuations is NULL, and a crash is seen in inlObjectNotify. A null check is needed.
  4. Also, the below assert in ContinuationHelpers.cpp is being triggered suggesting that the lock.wait use-case is not handled correctly (refer to the Java and native stacks below for more details).

The test needs to be run with -Xint -Xgcpolicy:nogc -XX:+YieldPinnedVirtualThreads to enable the base VM changes for JEP 491. Also, the GC and JIT need to be disabled as the GC and VM-JIT coordination changes for JEP 491 are still in progress.

STARTED    MonitorWaitNotify::testTimedWaitDuration2 'testTimedWaitDuration2()'
18:16:31.035 0x480100    j9vm.224    *   ** ASSERTION FAILED ** at /root/openj9-openjdk-jdk24/openj9/runtime/vm/ContinuationHelpers.cpp:366: ((__null == continuation->nextWaitingContinuation))

4XESTACKTRACE                at MonitorWaitNotify.testTimedWaitDuration2(MonitorWaitNotify.java:390)

#14 0x00007f0a14436644 in freeContinuation (currentThread=0x480100, continuationObject=0x70884d000, skipLocalCache=0) at /root/openj9-openjdk-jdk24/openj9/runtime/vm/ContinuationHelpers.cpp:366
#15 0x00007f0a14436efd in yieldContinuation (currentThread=0x480100, isFinished=1, returnState=1) at /root/openj9-openjdk-jdk24/openj9/runtime/vm/ContinuationHelpers.cpp:342
#16 0x00007f0a1443bfb7 in VM_BytecodeInterpreterCompressed::yieldContinuationImpl (_pc=<optimized out>, _sp=<optimized out>, this=<optimized out>) at /root/openj9-openjdk-jdk24/openj9/runtime/vm/BytecodeInterpreter.hpp:5782

fyi @tajila @fengxue-IS

@fengxue-IS
Copy link
Contributor

just checked JCL code which handles the Thread.interrupt() call, the InterruptedException is not thrown because we never used the port library wait mechanism and yet the vthread unblocking code in JCL didn't update the exception state either, I will write a PR today to address this.

@babsingh
Copy link
Contributor

@fengxue-IS Can you confirm if #20369 (comment) will only address point 2 from #20369 (comment)? Points 1, 3 and 4 from #20369 (comment) will still need to be addressed.

@fengxue-IS
Copy link
Contributor

@fengxue-IS Can you confirm if #20369 (comment) will only address point 2 from #20369 (comment)? Points 1, 3 and 4 from #20369 (comment) will still need to be addressed.

yes, 1,3,4 will still need to be addressed

babsingh added a commit to babsingh/openj9 that referenced this issue Mar 13, 2025
If a notify is issued before wait, then there waitingContinuations
will be NULL. In this case, the notify steps should not be executed
since there are no virtual threads waiting, and
waitingContinuations->vthread will be NULL.

Addresses point 3 in the below Github comment:
eclipse-openj9#20369 (comment).

Signed-off-by: Babneet Singh <[email protected]>
babsingh added a commit to babsingh/openj9 that referenced this issue Mar 13, 2025
If a notify is issued before wait, then there waitingContinuations
will be NULL. In this case, the notify steps should not be executed
since there are no virtual threads waiting, and
waitingContinuations->vthread will be NULL.

Addresses point 3 in the below Github comment:
eclipse-openj9#20369 (comment).

Signed-off-by: Babneet Singh <[email protected]>
babsingh added a commit to babsingh/openj9 that referenced this issue Mar 13, 2025
If a notify is issued before wait, then there waitingContinuations
will be NULL. In this case, the notify steps should not be executed
since there are no virtual threads waiting, and
waitingContinuations->vthread will be NULL.

Addresses point 3 in the below Github comment:
eclipse-openj9#20369 (comment).

Signed-off-by: Babneet Singh <[email protected]>
babsingh added a commit to babsingh/openj9 that referenced this issue Mar 13, 2025
If a notify is issued before wait, then there waitingContinuations
will be NULL. In this case, the notify steps should not be executed
since there are no virtual threads waiting, and
waitingContinuations->vthread will be NULL.

Addresses point 3 in the below Github comment:
eclipse-openj9#20369 (comment).

Signed-off-by: Babneet Singh <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants