JDK-8335134 : Test com/sun/jdi/BreakpointOnClassPrepare.java timeout
  • Type: Bug
  • Component: core-svc
  • Sub-Component: debugger
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: generic
  • Submitted: 2024-06-26
  • Updated: 2024-07-01
  • Resolved: 2024-06-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 23 JDK 24
23Fixed 24 masterFixed
Related Reports
Relates :  
Sub Tasks
JDK-8335137 :  
Description
test log snippet:
"MainThread" #31 [1560215] prio=5 os_prio=0 cpu=112.94ms elapsed=480.14s tid=0x00007f5cc41e82c0 nid=1560215 waiting on condition  [0x00007f5c6fa27000]
   java.lang.Thread.State: WAITING (parking)
	at jdk.internal.misc.Unsafe.park(java.base@24/Native Method)
	- parking to wait for  <0x000000011bbc0e80> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(java.base@24/LockSupport.java:371)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@24/AbstractQueuedSynchronizer.java:519)
	at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@24/ForkJoinPool.java:4021)
	at java.util.concurrent.ForkJoinPool.managedBlock(java.base@24/ForkJoinPool.java:3967)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@24/AbstractQueuedSynchronizer.java:1712)
	at java.lang.ProcessImpl.waitFor(java.base@24/ProcessImpl.java:425)
	at TestScaffold.waitForVMDisconnect(TestScaffold.java:781)
	- locked <0x000000011b7fe0f8> (a BreakpointOnClassPrepare)
	at TestScaffold.resumeToVMDisconnect(TestScaffold.java:1015)
	at TestScaffold.listenUntilVMDisconnect(TestScaffold.java:743)
	at BreakpointOnClassPrepare.runTests(BreakpointOnClassPrepare.java:148)
	at TestScaffold.startTests(TestScaffold.java:468)
	at BreakpointOnClassPrepare.main(BreakpointOnClassPrepare.java:96)

Got BreakpointEvent: 1 for thread instance of java.lang.Thread(name='MyThread-1', id=335)
Timeout signalled after 480 seconds
STDERR:
[1ms] run args: [BreakpointOnClassPrepareTarg, SUSPEND_NONE]
[173ms] Got ClassPrepareEvent: ClassPrepareEvent in thread MyThread-1
[224ms] FAILED: Exception occured in eventHandler: com.sun.jdi.ObjectCollectedException
	at java.base/java.lang.Thread.getStackTrace(Thread.java:2389)
	at TestScaffold.failure(TestScaffold.java:491)
	at TestScaffold$EventHandler.run(TestScaffold.java:298)
	at java.base/java.lang.Thread.run(Thread.java:1575)
com.sun.jdi.ObjectCollectedException
	at jdk.jdi/com.sun.tools.jdi.JDWPException.toJDIException(JDWPException.java:56)
	at jdk.jdi/com.sun.tools.jdi.ObjectReferenceImpl.referenceType(ObjectReferenceImpl.java:174)
	at jdk.jdi/com.sun.tools.jdi.ThreadReferenceImpl.toString(ThreadReferenceImpl.java:636)
	at java.base/java.lang.String.valueOf(String.java:4556)
	at BreakpointOnClassPrepare.breakpointReached(BreakpointOnClassPrepare.java:107)
	at TestScaffold$EventHandler.notifyEvent(TestScaffold.java:193)
	at TestScaffold$EventHandler.run(TestScaffold.java:277)
	at java.base/java.lang.Thread.run(Thread.java:1575)
Comments
A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/19976 Date: 2024-07-01 17:10:44 +0000
01-07-2024

Changeset: 4e8cbf88 Author: Chris Plummer <cjplummer@openjdk.org> Date: 2024-06-27 22:20:14 +0000 URL: https://git.openjdk.org/jdk/commit/4e8cbf884ab1eee9c3110712ab62edc706e948ba
27-06-2024

ILW=HLM=P3 This bug is a regression that will end up being backported to 21 and 23.
27-06-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/19910 Date: 2024-06-26 17:26:52 +0000
26-06-2024

It turns out that with SUSPEND_NONE it seems that the Thread has always terminated by the time breakpointReached() is called (I confirmed by calling ThreadReference.status()), and the ThreadReference.toString() works just fine in that case. So the only concern is if the Thread also gets collected after terminating, and that will be handled by catching the ObjectCollectedException.
26-06-2024

It looks like ThreadReference.toString() should be ok for terminated threads. It ends up in JVMTI GetThreadInfo(), which works for terminated threads.
26-06-2024

This seems to be the issue: com.sun.jdi.ObjectCollectedException at jdk.jdi/com.sun.tools.jdi.JDWPException.toJDIException(JDWPException.java:56) at jdk.jdi/com.sun.tools.jdi.ObjectReferenceImpl.referenceType(ObjectReferenceImpl.java:174) at jdk.jdi/com.sun.tools.jdi.ThreadReferenceImpl.toString(ThreadReferenceImpl.java:636) at java.base/java.lang.String.valueOf(String.java:4556) at BreakpointOnClassPrepare.breakpointReached(BreakpointOnClassPrepare.java:107) at TestScaffold$EventHandler.notifyEvent(TestScaffold.java:193) at TestScaffold$EventHandler.run(TestScaffold.java:277) at java.base/java.lang.Thread.run(Thread.java:1575) When the breakpoint event arrives, breakpointReached() does the following: System.out.println("Got BreakpointEvent: " + bkptCount + " for thread " + event.thread()); event.thread() returns a ThreadReference that there is then an implicit toString() done on, and JDWP is telling us that on the Thread instance on the debuggee side is already collected. My assumption here is that the thread has already exited, followed by a GC. This test has 3 modes. When the breakpoint is reached the suspend policy can be SUSPEND_ALL, SUSPEND_EVENT_THREAD, or SUSPEND_NONE. From the log we can see the SUSPEND_NONE mode is being used: command: driver BreakpointOnClassPrepare SUSPEND_NONE This means while the breakpoint event is being handled, the breakpoint thread continues to run and can exit. If there happens to be a GC after it exits, the Thread instance is collected and any attempt to access it via the ThreadReference mirror will result in ObjectCollectedException. I think the best fix is to just catch and ignore the ObjectCollectedException during this println(), especially when using SUSPEND_NONE. However, I'm a bit worried we can get other exceptions when doing ThreadReference.toString() if the Thread has exited, but is not collected yet. I'll need to look into that and make sure those exceptions are also covered. In the meantime, if this test is noisy due to this failure, I suggest just disabling the SUSPEND_NONE mode for now.
26-06-2024