Add a jcmd tool to print all threads and vthreads info (including unmounted vts and lock information)
唐佳未(佳未)
tjw378335 at alibaba-inc.com
Thu Apr 3 09:13:39 UTC 2025
I think it may be useful to add a tool which can print more information about the unmounted virtual threads after the JEP491.
I knew that the`jcmd Thread.dump_to_file` cmd could generate a json/text file to give a view of the all the threads and virtual threads but it lacks information about the locks after JEP491.
Our applications have used virtual threads (om pinned solved versions) on a large scale of machines and sometimes encounters deadlocks.
In practice, it is helpful to get the lock information about the unmounted threads to debug those deadlocks. We add a jcmd tools to get this information: https://github.com/openjdk/jdk/pull/24405 <https://github.com/openjdk/jdk/pull/24405 >
May it be commited to the openjdk/loom?
The logic of the `jcmd ThreadAndVThread.dump`:
1. get all threads and vthreads using a java call
2. print the stacktrace
2.1 print the javathread (including vt info) by a handshake
2.2 print the vthread
The way to get stack and lock information is like `jstack` impl.
We choose this way to get information because
1. Our application developers are more familiar to the output generated by the jstack tools.
2. It's wired to call into the vm to get lock information for each vthread if we choose to implement this in the `jcmd Thread.dump_to_file` logic.
Part of the output we get for the new tool `jcmd ThreadAndVThread.dump`:
"vthread-3" #48 Unmounted virtual thread
at jdk.internal.vm.Continuation.yield0(java.base at 25-internal/Continuation.java:365)
- parking to wait for <0x000000011f7efe70> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at jdk.internal.vm.Continuation.yield(java.base at 25-internal/Continuation.java:357)
at java.lang.VirtualThread.yieldContinuation(java.base at 25-internal/VirtualThread.java:543)
at java.lang.VirtualThread.park(java.base at 25-internal/VirtualThread.java:746)
at java.lang.System$1.parkVirtualThread(java.base at 25-internal/System.java:2271)
at java.util.concurrent.locks.LockSupport.park(java.base at 25-internal/LockSupport.java:367)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base at 25-internal/AbstractQueuedSynchronizer.java:519)
at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base at 25-internal/ForkJoinPool.java:3945)
at java.util.concurrent.ForkJoinPool.managedBlock(java.base at 25-internal/ForkJoinPool.java:3891)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base at 25-internal/AbstractQueuedSynchronizer.java:1751)
at java.lang.ProcessImpl.waitFor(java.base at 25-internal/ProcessImpl.java:413)
at jdk.test.lib.process.OutputBuffer$LazyOutputBuffer.waitFor(OutputBuffer.java:162)
at jdk.test.lib.process.OutputAnalyzer.waitFor(OutputAnalyzer.java:117)
at jdk.test.lib.process.ProcessTools.executeProcess(ProcessTools.java:727)
at jdk.test.lib.process.ProcessTools.executeProcess(ProcessTools.java:695)
at jdk.test.lib.process.ProcessTools.executeProcess(ProcessTools.java:682)
at TestJcmdDumpThreadAndVThread.lambda$main$3(TestJcmdDumpThreadAndVThread.java:73)
at TestJcmdDumpThreadAndVThread$$Lambda/0x00007ff45b005000.run(Unknown Source)
at java.lang.Thread.runWith(java.base at 25-internal/Thread.java:1460)
at java.lang.VirtualThread.run(java.base at 25-internal/VirtualThread.java:466)
at java.lang.VirtualThread$VThreadContinuation$1.run(java.base at 25-internal/VirtualThread.java:258)
at jdk.internal.vm.Continuation.enter0(java.base at 25-internal/Continuation.java:325)
at jdk.internal.vm.Continuation.enter(java.base at 25-internal/Continuation.java:316)
"vthread-0" #44 Unmounted virtual thread
at java.lang.Object.wait0(java.base at 25-internal/Native Method)
at java.lang.Object.wait(java.base at 25-internal/Object.java:382)
at java.lang.Object.wait(java.base at 25-internal/Object.java:351)
at TestJcmdDumpThreadAndVThread.lambda$main$0(TestJcmdDumpThreadAndVThread.java:31)
- waiting to lock <0x000000011f5f7e00> (a TestJcmdDumpThreadAndVThread)
at TestJcmdDumpThreadAndVThread$$Lambda/0x00007ff45b0018b0.run(Unknown Source)
at java.lang.Thread.runWith(java.base at 25-internal/Thread.java:1460)
at java.lang.VirtualThread.run(java.base at 25-internal/VirtualThread.java:466)
at java.lang.VirtualThread$VThreadContinuation$1.run(java.base at 25-internal/VirtualThread.java:258)
at jdk.internal.vm.Continuation.enter0(java.base at 25-internal/Continuation.java:325)
at jdk.internal.vm.Continuation.enter(java.base at 25-internal/Continuation.java:316)
"vthread-1" #46 Unmounted virtual thread
at jdk.internal.vm.Continuation.yield0(java.base at 25-internal/Continuation.java:365)
- parking to wait for <0x000000011f5f80b8> (a java.util.concurrent.Semaphore$NonfairSync)
at jdk.internal.vm.Continuation.yield(java.base at 25-internal/Continuation.java:357)
at java.lang.VirtualThread.yieldContinuation(java.base at 25-internal/VirtualThread.java:543)
at java.lang.VirtualThread.park(java.base at 25-internal/VirtualThread.java:746)
at java.lang.System$1.parkVirtualThread(java.base at 25-internal/System.java:2271)
at java.util.concurrent.locks.LockSupport.park(java.base at 25-internal/LockSupport.java:221)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base at 25-internal/AbstractQueuedSynchronizer.java:789)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(java.base at 25-internal/AbstractQueuedSynchronizer.java:1138)
at java.util.concurrent.Semaphore.acquire(java.base at 25-internal/Semaphore.java:318)
at TestJcmdDumpThreadAndVThread.lambda$main$1(TestJcmdDumpThreadAndVThread.java:41)
- locked <0x000000011f5f7e00> (a TestJcmdDumpThreadAndVThread)
at TestJcmdDumpThreadAndVThread$$Lambda/0x00007ff45b001ad8.run(Unknown Source)
at java.lang.Thread.runWith(java.base at 25-internal/Thread.java:1460)
at java.lang.VirtualThread.run(java.base at 25-internal/VirtualThread.java:466)
at java.lang.VirtualThread$VThreadContinuation$1.run(java.base at 25-internal/VirtualThread.java:258)
at jdk.internal.vm.Continuation.enter0(java.base at 25-internal/Continuation.java:325)
at jdk.internal.vm.Continuation.enter(java.base at 25-internal/Continuation.java:316)
"vthread-2" #47 Unmounted virtual thread
at TestJcmdDumpThreadAndVThread.lambda$main$2(TestJcmdDumpThreadAndVThread.java:56)
- waiting to lock <0x000000011f5f7e00> (a TestJcmdDumpThreadAndVThread)
at TestJcmdDumpThreadAndVThread$$Lambda/0x00007ff45b001d00.run(Unknown Source)
at java.lang.Thread.runWith(java.base at 25-internal/Thread.java:1460)
at java.lang.VirtualThread.run(java.base at 25-internal/VirtualThread.java:466)
at java.lang.VirtualThread$VThreadContinuation$1.run(java.base at 25-internal/VirtualThread.java:258)
at jdk.internal.vm.Continuation.enter0(java.base at 25-internal/Continuation.java:325)
at jdk.internal.vm.Continuation.enter(java.base at 25-internal/Continuation.java:316)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20250403/d6bc32a9/attachment-0001.htm>
More information about the loom-dev
mailing list