On Thu, 24 Sep 2026 04:50:13 GMT, Yasumasa Suenaga <[email protected]> wrote:

> serviceability/sa/TestJhsdbJstackMixedWithXComp.java#xcomp failed due because 
> stderr has message to report DebuggerException caused by unknown DWARF opcode.
> 
> During the discussion, we've reached the conclusion that it is better to add 
> `print_waring()` to notice this case (it is handled in 
> [JDK-8392120](https://bugs.openjdk.org/browse/JDK-8392120): PR #33047), and 
> the exception should not be shown in normal.
> 
> Thus this PR proposes to show DebuggerException when `LIBSAPROC_DEBUG` 
> environment variable is set in mixed jstack.
> 
> ---------
> - [x] I confirm that I make this contribution in accordance with the [OpenJDK 
> Interim AI Policy](https://openjdk.org/legal/ai).

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java line 197:

> 195:                   f = f.sender(th, senderSP, senderFP, senderPC);
> 196:                }
> 197:             } catch (DebuggerException dex) {

I'm not sure this should be fully silent. `cdbg.topFrameForThread(th)` is the 
first statement of the per-thread try block, before the `----------------- 
<tid> -----------------` header is printed (PStack.java:103-106). When the 
exception comes from there — which is exactly what the stack trace in 
JDK-8392132 shows (`LinuxAMD64CFrame.getTopFrame` -> 
`LinuxCDebugger.topFrameForThread` -> `PStack.run`) — the thread is not printed 
at all, rather than printed empty. The same applies to the `pstack` command in 
HSDB/CLHSDB and to the remote debug server, which reuse PStack.

So after this change a thread can silently disappear from the output with no 
hint that anything went wrong. That is the point Chris raised in the bug 
("throwing the exception is too severe in this case"), and I don't think it was 
really settled.

Would it be better to report it inline instead of dropping it? Something like:

   } catch (DebuggerException dex) {
      // DWARF unwinding legitimately fails for some PCs (e.g. unsupported
      // DWARF instructions or missing debug info). Report it in the stack
      // output rather than on stderr.
      out.println("<could not unwind thread: " + dex.getMessage() + ">");
   }

That keeps stderr empty, so `out.stderrShouldBeEmptyIgnoreVMWarnings()` in 
TestJhsdbJstackMixedWithXComp still passes, while making the truncation visible 
to the user.

(Note: the transcript in the bug shows an empty thread 546, but with the 
current ordering in PStack I believe the entry would be dropped entirely. If 
you can reproduce, it would be worth confirming which one happens now.)

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java line 200:

> 198:                // DebuggerException would be shown if LIBSAPROC_DEBUG is 
> set.
> 199:                // The process should be continued for other threads.
> 200:                if (System.getenv("LIBSAPROC_DEBUG") != null) {

This catch is broader than the case described in the bug. Today the only place 
a DWARF failure is deliberately swallowed is the signal trampoline case in 
`DwarfCFrame.createDwarfParser` (DwarfCFrame.java:61-70), whose comment 
explicitly says the exception is rethrown otherwise; 
`LinuxAMD64CFrame.sender()` follows the same policy and rethrows unless the 
caller is a signal trampoline (LinuxAMD64CFrame.java:136-146). This change 
reverses that decision one layer up.

`DebuggerException` is also libsaproc's generic failure signal, not only the 
DWARF one — for example "Error getting symbol string" and "Could not demangle" 
(LinuxDebuggerLocal.cpp:620, 630) are reachable from `f.closestSymbolToPC()` 
inside this same loop, and all the `LinuxDebugger` read methods declare it. 
Those failures would now be hidden too unless LIBSAPROC_DEBUG is set.

(UnmappedAddressException/UnalignedAddressException are not affected — they 
extend AddressException, not DebuggerException — so that part is fine.)

Could you either document in the comment that this is an intentional, known 
degradation and reference the JBS issue, or handle the failure where the walk 
actually fails? For the top frame, `LinuxAMD64CFrame.getFrameFromReg` could 
fall back to a frame without DWARF the way `sender()` does for senders, which 
would at least give the user the top frame instead of nothing.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/33048#discussion_r4091719717
PR Review Comment: https://git.openjdk.org/jdk/pull/33048#discussion_r4091730466

Reply via email to