RFR: 8369505: jhsdb jstack cannot handle continuation stub
Patricio Chilano Mateo
pchilanomate at openjdk.org
Tue Oct 14 18:14:34 UTC 2025
On Sat, 11 Oct 2025 05:09:31 GMT, Chris Plummer <cjplummer at openjdk.org> wrote:
> > @plummercj Did you run `jhsdb jstack --mixed` ? StubRoutine would appear in mixed mode only I think (in Linux, at least).
>
> I did not, and unfortunately --mixed is not support on OSX.
>
Ok, that’s why I wasn’t seeing `<StubRoutines (continuation stubs)>` either. I removed `—mixed` because it wasn’t working for me, only the top native frame was shown in the stacktrace (on linux-x64). I could still reproduce the assert without `—mixed` so I continued testing that way assuming the output for the `enterSpecial` frame would be the same in both modes.
Now, testing on linux-aarch64, `—mixed` mode works and I can see `<StubRoutines (continuation stubs)>` for the `enterSpecial` frame. Looking at the code, I see the difference with mixed mode is the way we walk the stack. Even for Java frames the sender is always obtained through this method [1], relying basically on the FP. Then once we get to the frame with pc equal to the return barrier, here [2] we will just branch to the else case and print it as a continuation stub instead of the `enterSpecial` frame.
I was also curious how we can walk compiled frames this way, since the FP will not contain in general a valid link unless `-XX:+PreserveFramePointer` is set. So I added `-Xcomp` to `LingeredApp.startApp` and I see that we indeed fail to walk the stack:
----------------- 2943661 -----------------
"ForkJoinPool-1-worker-2" #30 daemon prio=5 tid=0x0000ffff08007f30 nid=2943661 runnable [0x0000ffff695e1000]
java.lang.Thread.State: RUNNABLE
JavaThread state: _thread_in_native
0x0000ffff9bb40b24 __clock_nanosleep + 0x84
0x0000ffff9bb45c0c __GI___nanosleep + 0x1c
0x0000ffff9bb45acc __sleep + 0x4c
0x0000ffff836fb338 <nep_invoker_blob>
0x0000ffff7c802ef8 * java.lang.invoke.LambdaForm$MH+0x0000000601047800.invoke(java.lang.Object, long, int) bci:10 (Compiled frame)
* java.lang.invoke.LambdaForm$MH+0x000000060104d400.invokeExact_MT(java.lang.Object, long, int, java.lang.Object) bci:21 (Compiled frame)
0x910023e12a0003e2 ????????
----------------- 2943659 -----------------
When setting` -XX:+PreserveFramePointer` we can walk them again (also tweaked the code to print the correct `enterSpecial` frame):
----------------- 2947348 -----------------
"ForkJoinPool-1-worker-2" #30 daemon prio=5 tid=0x0000ffff1c008040 nid=2947348 runnable [0x0000ffff7c8dd000]
java.lang.Thread.State: RUNNABLE
JavaThread state: _thread_in_native
0x0000ffffaee18b24 __clock_nanosleep + 0x84
0x0000ffffaee1dc0c __GI___nanosleep + 0x1c
0x0000ffffaee1dacc __sleep + 0x4c
0x0000ffff976faa38 <nep_invoker_blob>
0x0000ffff90806f3c * java.lang.invoke.LambdaForm$MH+0x000007e001047800.invoke(java.lang.Object, long, int) bci:10 (Compiled frame)
0x0000ffff90bad354 * java.lang.invoke.LambdaForm$MH+0x000007e00104d400.invokeExact_MT(java.lang.Object, long, int, java.lang.Object) bci:21 (Compiled frame)
0x0000ffff97597d60 * jdk.internal.foreign.abi.DowncallStub+0x000007e001048800.invoke(java.lang.foreign.SegmentAllocator, java.lang.foreign.MemorySegment, int) bci:44 (Interpreted frame)
0x0000ffff908b7a70 * java.lang.invoke.LambdaForm$DMH+0x000007e001048c00.invokeStaticInit(java.lang.Object, java.lang.Object, java.lang.Object, int) bci:14 (Compiled frame)
0x0000ffff90b9b710 * java.lang.invoke.LambdaForm$MH+0x000007e00104c800.invoke(java.lang.Object, int) bci:44 (Compiled frame)
0x0000ffff90b9041c * java.lang.invoke.LambdaForm$MH+0x000007e00104c400.invoke_MT(java.lang.Object, int, java.lang.Object) bci:18 (Compiled frame)
0x0000ffff97597f30 * LingeredAppWithVirtualThread.run() bci:15 line:65 (Interpreted frame)
0x0000ffff975963b8 * jdk.internal.vm.Continuation.enterSpecial(jdk.internal.vm.Continuation, boolean, boolean) bci:0 (Compiled frame)
0x0000ffff97fa5fbc * jdk.internal.vm.Continuation.run() bci:152 line:251 (Compiled frame)
0x0000ffff90b85888 * java.lang.VirtualThread.runContinuation() bci:100 line:293 (Compiled frame)
0x0000ffff97fa3eb0 * java.lang.VirtualThread$$Lambda+0x000007e001034c88.run() bci:4 (Compiled frame)
0x0000ffff90b8445c * java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec() bci:4 line:1596 (Compiled frame)
0x0000ffff90b83298 * java.util.concurrent.ForkJoinTask.doExec() bci:10 line:511 (Compiled frame)
0x0000ffff90b81e2c * java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(java.util.concurrent.ForkJoinTask, int) bci:5 line:1450 (Compiled frame)
* java.util.concurrent.ForkJoinPool.runWorker(java.util.concurrent.ForkJoinPool$WorkQueue) bci:364 line:2019 (Compiled frame)
0x0000ffff97fa03a8 * java.util.concurrent.ForkJoinWorkerThread.run() bci:31 line:187 (Compiled frame)
0x0000ffff9759349c <StubRoutines (initial stubs)>
0x0000ffffad95020c JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*) + 0x45c
0x0000ffffad950880 JavaCalls::call_virtual(JavaValue*, Klass*, Symbol*, Symbol*, JavaCallArguments*, JavaThread*) + 0x278
0x0000ffffad950e14 JavaCalls::call_virtual(JavaValue*, Handle, Klass*, Symbol*, Symbol*, JavaThread*) + 0x8c
0x0000ffffadaee66c thread_entry(JavaThread*, JavaThread*) + 0xc4
0x0000ffffad98de68 JavaThread::thread_main_inner() + 0x108
0x0000ffffae301efc Thread::call_run() + 0xac
0x0000ffffadfe105c thread_native_entry(Thread*) + 0x12c
0x0000ffffaede3b50 start_thread + 0x300
I would have expected that `mixed` mode walked the stack similar to how we do it in the VM with `NativeStackPrinter` using `frame::next_frame()`, i.e we change how we get the sender based on the frame.
Anyways, I was just curious about the difference in output with `mixed` mode.
[1] https://github.com/openjdk/jdk/blob/d6537c6d3ee6d7a59d609b277f0538da0afb0fbf/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/aarch64/LinuxAARCH64CFrame.java#L56
[2] https://github.com/openjdk/jdk/blob/d6537c6d3ee6d7a59d609b277f0538da0afb0fbf/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java#L148
-------------
PR Comment: https://git.openjdk.org/jdk/pull/27728#issuecomment-3403057882
More information about the serviceability-dev
mailing list