Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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 is 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);
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -278,7 +291,7 @@ public synchronized boolean detach() {
return false;
}

threadList = null;
javaThreadList = null;
loadObjectList = null;

if (isCore) {
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 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
Expand All @@ -25,6 +25,8 @@
package sun.jvm.hotspot.debugger.cdbg;

import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.utilities.*;

/** Models a "C" programming language frame on the stack -- really
just an arbitrary frame with hooks to access C and C++ debug
Expand All @@ -37,7 +39,7 @@ public interface CFrame {
public CFrame sender(ThreadProxy th);

/** Find sender frame with given FP and PC */
public default CFrame sender(ThreadProxy th, Address fp, Address pc) {
public default CFrame sender(ThreadProxy th, Address sp, Address fp, Address pc) {
return sender(th);
}

Expand Down Expand Up @@ -70,4 +72,9 @@ public default CFrame sender(ThreadProxy th, Address fp, Address pc) {
/** Visit all local variables in this frame if debug information is
available. Automatically descends into compound types and arrays. */
public void iterateLocals(ObjectVisitor v);

/** Get Frame instance assosiated with this CFrame. */
public default Frame toFrame() {
throw new UnsupportedPlatformException();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -81,9 +81,11 @@ public CFrame topFrameForThread(ThreadProxy thread) throws DebuggerException {
String cpu = dbg.getCPU();
if (cpu.equals("amd64")) {
AMD64ThreadContext context = (AMD64ThreadContext) thread.getContext();
Address sp = context.getRegisterAsAddress(AMD64ThreadContext.RSP);
if (sp == null) return null;
Address pc = context.getRegisterAsAddress(AMD64ThreadContext.RIP);
if (pc == null) return null;
return LinuxAMD64CFrame.getTopFrame(dbg, pc, context);
return LinuxAMD64CFrame.getTopFrame(dbg, sp, pc, context);
} else if (cpu.equals("ppc64")) {
PPC64ThreadContext context = (PPC64ThreadContext) thread.getContext();
Address sp = context.getRegisterAsAddress(PPC64ThreadContext.SP);
Expand All @@ -93,18 +95,22 @@ public CFrame topFrameForThread(ThreadProxy thread) throws DebuggerException {
return new LinuxPPC64CFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize());
} else if (cpu.equals("aarch64")) {
AARCH64ThreadContext context = (AARCH64ThreadContext) thread.getContext();
Address sp = context.getRegisterAsAddress(AARCH64ThreadContext.SP);
if (sp == null) return null;
Address fp = context.getRegisterAsAddress(AARCH64ThreadContext.FP);
if (fp == null) return null;
Address pc = context.getRegisterAsAddress(AARCH64ThreadContext.PC);
if (pc == null) return null;
return new LinuxAARCH64CFrame(dbg, fp, pc);
return new LinuxAARCH64CFrame(dbg, sp, fp, pc);
} else if (cpu.equals("riscv64")) {
RISCV64ThreadContext context = (RISCV64ThreadContext) thread.getContext();
Address sp = context.getRegisterAsAddress(RISCV64ThreadContext.SP);
if (sp == null) return null;
Address fp = context.getRegisterAsAddress(RISCV64ThreadContext.FP);
if (fp == null) return null;
Address pc = context.getRegisterAsAddress(RISCV64ThreadContext.PC);
if (pc == null) return null;
return new LinuxRISCV64CFrame(dbg, fp, pc);
return new LinuxRISCV64CFrame(dbg, sp, fp, pc);
} else {
// Runtime exception thrown by LinuxThreadContextFactory if unknown cpu
ThreadContext context = thread.getContext();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -30,10 +30,14 @@
import sun.jvm.hotspot.debugger.linux.*;
import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.debugger.cdbg.basic.*;
import sun.jvm.hotspot.code.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.runtime.aarch64.*;

public final class LinuxAARCH64CFrame extends BasicCFrame {
public LinuxAARCH64CFrame(LinuxDebugger dbg, Address fp, Address pc) {
public LinuxAARCH64CFrame(LinuxDebugger dbg, Address sp, Address fp, Address pc) {
super(dbg.getCDebugger());
this.sp = sp;
this.fp = fp;
this.pc = pc;
this.dbg = dbg;
Expand All @@ -55,11 +59,11 @@ public Address localVariableBase() {

@Override
public CFrame sender(ThreadProxy thread) {
return sender(thread, null, null);
return sender(thread, null, null, null);
}

@Override
public CFrame sender(ThreadProxy thread, Address nextFP, Address nextPC) {
public CFrame sender(ThreadProxy thread, Address nextSP, Address nextFP, Address nextPC) {
// Check fp
// Skip if both nextFP and nextPC are given - do not need to load from fp.
if (nextFP == null && nextPC == null) {
Expand All @@ -86,7 +90,32 @@ public CFrame sender(ThreadProxy thread, Address nextFP, Address nextPC) {
if (nextPC == null) {
return null;
}
return new LinuxAARCH64CFrame(dbg, nextFP, nextPC);

if (nextSP == null) {
CodeCache cc = VM.getVM().getCodeCache();
CodeBlob currentBlob = cc.findBlobUnsafe(pc());

// This case is different from HotSpot. See JDK-8371194 for details.
if (currentBlob != null && (currentBlob.isContinuationStub() || currentBlob.isNativeMethod())) {
// Use FP since it should always be valid for these cases.
// TODO: These should be walked as Frames not CFrames.
nextSP = fp.addOffsetTo(2 * ADDRESS_SIZE);
} else {
CodeBlob codeBlob = cc.findBlobUnsafe(nextPC);
boolean useCodeBlob = codeBlob != null && codeBlob.getFrameSize() > 0;
nextSP = useCodeBlob ? nextFP.addOffsetTo((2 * ADDRESS_SIZE) - codeBlob.getFrameSize()) : nextFP;
}
}
if (nextSP == null) {
return null;
}

return new LinuxAARCH64CFrame(dbg, nextSP, nextFP, nextPC);
}

@Override
public Frame toFrame() {
return new AARCH64Frame(sp, fp, pc);
}

// package/class internals only
Expand Down
Loading