On Thu, 13 Nov 2025 12:53:50 GMT, Yasumasa Suenaga <[email protected]> wrote:
>> We've fixed mixed mode jstack for the debuggee running with `-Xcomp` in >> [JDK-8370176](https://bugs.openjdk.org/browse/JDK-8370176), but it was not >> enough. We need to handle like unifying `CFrame` and `Frame` in stack >> unwinding as possible, and need to change how to get caller SP/FP from stack. >> >> This PR works fine on both Linux AMD64 and Linux AArch64. All of >> `hotspot/jtreg/serviceability/sa` tests have been passed on both platforms. >> >> Big thanks to @pchilano for your help! > > Yasumasa Suenaga has updated the pull request incrementally with one > additional commit since the last revision: > > Update for Linux PPC64 and RISC-V Ok, I confirmed `VM.initialize()` would be called at the end of `setupVM()`. So I updated a patch for `BsdDebuggerLocal` to initialize thread list in lazily. Can you try it again? Sorry for the trouble. diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java index 10f6881d010..891ebc91f49 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,9 @@ package sun.jvm.hotspot.debugger.bsd; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.stream.IntStream; import sun.jvm.hotspot.debugger.Address; import sun.jvm.hotspot.debugger.DebuggerBase; @@ -75,10 +77,11 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger { // CDebugger support private BsdCDebugger cdbg; - // threadList and loadObjectList are filled by attach0 method - private List<ThreadProxy> threadList; + // loadObjectList are filled by attach0 method private List<LoadObject> loadObjectList; + private List<JavaThread> javaThreadList; + // called by native method lookupByAddress0 private ClosestSymbol createClosestSymbol(String name, long offset) { return new ClosestSymbol(name, offset); @@ -241,10 +244,21 @@ private void findABIVersion() throws DebuggerException { } } + private void fillJavaThreadList() { + // TODO: thread list on macOS is now supported for corefile only. + if (!isCore && isDarwin) { + javaThreadList = Collections.emptyList(); + } else { + Threads threads = VM.getVM().getThreads(); + javaThreadList = IntStream.range(0, threads.getNumberOfThreads()) + .mapToObj(threads::getJavaThreadAt) + .toList(); + } + } + /** From the Debugger interface via JVMDebugger */ public synchronized void attach(int processID) throws DebuggerException { checkAttached(); - threadList = new ArrayList<>(); loadObjectList = new ArrayList<>(); class AttachTask implements WorkerThreadTask { int pid; @@ -264,7 +278,6 @@ public void doit(BsdDebuggerLocal debugger) { /** From the Debugger interface via JVMDebugger */ public synchronized void attach(String execName, String coreName) { checkAttached(); - threadList = new ArrayList<>(); loadObjectList = new ArrayList<>(); attach0(execName, coreName); attached = true; @@ -278,7 +291,7 @@ public synchronized boolean detach() { return false; } - threadList = null; + javaThreadList = null; loadObjectList = null; if (isCore) { @@ -492,7 +505,12 @@ public Address newAddress(long value) { /** From the BsdCDebugger interface */ public List<ThreadProxy> getThreadList() { requireAttach(); - return threadList; + if (javaThreadList == null) { + fillJavaThreadList(); + } + return javaThreadList.stream() + .map(JavaThread::getThreadProxy) + .toList(); } /** From the BsdCDebugger interface */ @@ -561,21 +579,19 @@ public void doit(BsdDebuggerLocal debugger) { /** this functions used for core file reading and called from native attach0, it returns an array of long integers as [thread_id, stack_start, stack_end, thread_id, stack_start, stack_end, ....] for - all java threads recorded in Threads. Also adds the ThreadProxy to threadList */ + all java threads recorded in Threads. */ public long[] getJavaThreadsInfo() { requireAttach(); - Threads threads = VM.getVM().getThreads(); - int len = threads.getNumberOfThreads(); - long[] result = new long[len * 3]; // triple + if (javaThreadList == null) { + fillJavaThreadList(); + } + long[] result = new long[javaThreadList.size() * 3]; // triple long beg, end; int i = 0; - for (int k = 0; k < threads.getNumberOfThreads(); k++) { - JavaThread t = threads.getJavaThreadAt(k); + for (var t : javaThreadList) { end = t.getStackBaseValue(); beg = end - t.getStackSize(); - BsdThread bsdt = (BsdThread)t.getThreadProxy(); - long uid = bsdt.getUniqueThreadId(); - if (threadList != null) threadList.add(bsdt); + long uid = ((BsdThread)t.getThreadProxy()).getUniqueThreadId(); result[i] = uid; result[i + 1] = beg; result[i + 2] = end; ------------- PR Comment: https://git.openjdk.org/jdk/pull/28284#issuecomment-3555136250
