Skip to content

Commit 2c40de5

Browse files
authored
Merge pull request #3 from snake66/jdk26-freebsd-backport-sa-fix
Backport SA fixes for FreeBSD
2 parents c79777f + e995023 commit 2c40de5

File tree

4 files changed

+69
-142
lines changed

4 files changed

+69
-142
lines changed

src/jdk.hotspot.agent/bsd/native/libsaproc/BsdDebuggerLocal.cpp

Lines changed: 2 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,10 @@
3535
#define amd64 1
3636
#endif
3737

38-
#if defined(i386) && !defined(i586)
39-
#define i586 1
40-
#endif
41-
42-
#ifdef i586
43-
#include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"
44-
#endif
45-
4638
#ifdef amd64
4739
#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
4840
#endif
4941

50-
#if defined(sparc) || defined(sparcv9)
51-
#include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"
52-
#endif
53-
5442
#if defined(ppc64) || defined(ppc64le)
5543
#include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h"
5644
#endif
@@ -115,7 +103,6 @@ struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
115103
extern "C"
116104
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0
117105
(JNIEnv *env, jclass cls) {
118-
jclass listClass;
119106

120107
if (init_libproc(getenv("LIBSAPROC_DEBUG") != NULL) != true) {
121108
THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");
@@ -139,8 +126,9 @@ JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0
139126
getThreadForThreadId_ID = env->GetMethodID(cls, "getThreadForThreadId",
140127
"(J)Lsun/jvm/hotspot/debugger/ThreadProxy;");
141128
CHECK_EXCEPTION;
129+
142130
// java.util.List method we call
143-
listClass = env->FindClass("java/util/List");
131+
jclass listClass = env->FindClass("java/util/List");
144132
CHECK_EXCEPTION;
145133
listAdd_ID = env->GetMethodID(listClass, "add", "(Ljava/lang/Object;)Z");
146134
CHECK_EXCEPTION;
@@ -350,15 +338,9 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_
350338
}
351339

352340
#undef NPRGREG
353-
#ifdef i586
354-
#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
355-
#endif
356341
#ifdef amd64
357342
#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
358343
#endif
359-
#if defined(sparc) || defined(sparcv9)
360-
#define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
361-
#endif
362344
#if defined(ppc64) || defined(ppc64le)
363345
#define NPRGREG sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_NPRGREG
364346
#endif
@@ -372,27 +354,6 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_
372354

373355
#undef REG_INDEX
374356

375-
#ifdef i586
376-
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg
377-
378-
regs[REG_INDEX(GS)] = (uintptr_t) gregs.r_gs;
379-
regs[REG_INDEX(FS)] = (uintptr_t) gregs.r_fs;
380-
regs[REG_INDEX(ES)] = (uintptr_t) gregs.r_es;
381-
regs[REG_INDEX(DS)] = (uintptr_t) gregs.r_ds;
382-
regs[REG_INDEX(EDI)] = (uintptr_t) gregs.r_edi;
383-
regs[REG_INDEX(ESI)] = (uintptr_t) gregs.r_esi;
384-
regs[REG_INDEX(FP)] = (uintptr_t) gregs.r_ebp;
385-
regs[REG_INDEX(SP)] = (uintptr_t) gregs.r_isp;
386-
regs[REG_INDEX(EBX)] = (uintptr_t) gregs.r_ebx;
387-
regs[REG_INDEX(EDX)] = (uintptr_t) gregs.r_edx;
388-
regs[REG_INDEX(ECX)] = (uintptr_t) gregs.r_ecx;
389-
regs[REG_INDEX(EAX)] = (uintptr_t) gregs.r_eax;
390-
regs[REG_INDEX(PC)] = (uintptr_t) gregs.r_eip;
391-
regs[REG_INDEX(CS)] = (uintptr_t) gregs.r_cs;
392-
regs[REG_INDEX(SS)] = (uintptr_t) gregs.r_ss;
393-
394-
#endif /* i586 */
395-
396357
#ifdef amd64
397358
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg
398359

@@ -430,38 +391,6 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_
430391

431392
#endif /* amd64 */
432393

433-
#if defined(sparc) || defined(sparcv9)
434-
435-
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_##reg
436-
437-
#ifdef _LP64
438-
regs[REG_INDEX(R_PSR)] = gregs.tstate;
439-
regs[REG_INDEX(R_PC)] = gregs.tpc;
440-
regs[REG_INDEX(R_nPC)] = gregs.tnpc;
441-
regs[REG_INDEX(R_Y)] = gregs.y;
442-
#else
443-
regs[REG_INDEX(R_PSR)] = gregs.psr;
444-
regs[REG_INDEX(R_PC)] = gregs.pc;
445-
regs[REG_INDEX(R_nPC)] = gregs.npc;
446-
regs[REG_INDEX(R_Y)] = gregs.y;
447-
#endif
448-
regs[REG_INDEX(R_G0)] = 0 ;
449-
regs[REG_INDEX(R_G1)] = gregs.u_regs[0];
450-
regs[REG_INDEX(R_G2)] = gregs.u_regs[1];
451-
regs[REG_INDEX(R_G3)] = gregs.u_regs[2];
452-
regs[REG_INDEX(R_G4)] = gregs.u_regs[3];
453-
regs[REG_INDEX(R_G5)] = gregs.u_regs[4];
454-
regs[REG_INDEX(R_G6)] = gregs.u_regs[5];
455-
regs[REG_INDEX(R_G7)] = gregs.u_regs[6];
456-
regs[REG_INDEX(R_O0)] = gregs.u_regs[7];
457-
regs[REG_INDEX(R_O1)] = gregs.u_regs[8];
458-
regs[REG_INDEX(R_O2)] = gregs.u_regs[ 9];
459-
regs[REG_INDEX(R_O3)] = gregs.u_regs[10];
460-
regs[REG_INDEX(R_O4)] = gregs.u_regs[11];
461-
regs[REG_INDEX(R_O5)] = gregs.u_regs[12];
462-
regs[REG_INDEX(R_O6)] = gregs.u_regs[13];
463-
regs[REG_INDEX(R_O7)] = gregs.u_regs[14];
464-
#endif /* sparc */
465394
#if defined(ppc64) || defined(ppc64le)
466395
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_##reg
467396

src/jdk.hotspot.agent/bsd/native/libsaproc/ps_proc.c

Lines changed: 21 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -49,65 +49,38 @@ typedef enum {
4949
ATTACH_THREAD_DEAD
5050
} attach_state_t;
5151

52-
static inline uintptr_t align(uintptr_t ptr, size_t size) {
53-
return (ptr & ~(size - 1));
54-
}
55-
5652
// ---------------------------------------------
5753
// ptrace functions
5854
// ---------------------------------------------
5955

6056
// read "size" bytes of data from "addr" within the target process.
61-
// unlike the standard ptrace() function, process_read_data() can handle
62-
// unaligned address - alignment check, if required, should be done
63-
// before calling process_read_data.
57+
//
58+
// On BSD ptrace(2) does not have any alignment requirements on the remote process' address
6459

6560
static bool process_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
66-
int rslt;
67-
size_t i, words;
68-
uintptr_t end_addr = addr + size;
69-
uintptr_t aligned_addr = align(addr, sizeof(int));
70-
71-
if (aligned_addr != addr) {
72-
char *ptr = (char *)&rslt;
73-
errno = 0;
74-
rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
75-
if (errno) {
76-
print_error("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
77-
return false;
78-
}
79-
for (; aligned_addr != addr; aligned_addr++, ptr++);
80-
for (; ((intptr_t)aligned_addr % sizeof(int)) && aligned_addr < end_addr;
81-
aligned_addr++)
82-
*(buf++) = *(ptr++);
83-
}
8461

85-
words = (end_addr - aligned_addr) / sizeof(int);
62+
struct ptrace_io_desc piod = {
63+
.piod_op = PIOD_READ_D,
64+
.piod_offs = (void *) addr,
65+
.piod_addr = (void *) buf,
66+
.piod_len = size
67+
};
8668

87-
// assert((intptr_t)aligned_addr % sizeof(int) == 0);
88-
for (i = 0; i < words; i++) {
89-
errno = 0;
90-
rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
91-
if (errno) {
92-
print_error("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
93-
return false;
94-
}
95-
*(int *)buf = rslt;
96-
buf += sizeof(int);
97-
aligned_addr += sizeof(int);
69+
errno = 0;
70+
int rc = ptrace(PT_IO, ph->pid, (caddr_t) &piod, 0);
71+
72+
if (rc < 0 || errno != 0) {
73+
print_error("ptrace(PT_IO, ..) failed with errno = %d for %d bytes @ %lx, %d bytes read\n",
74+
errno, size, addr, piod.piod_len);
75+
return false;
9876
}
9977

100-
if (aligned_addr != end_addr) {
101-
char *ptr = (char *)&rslt;
102-
errno = 0;
103-
rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
104-
if (errno) {
105-
print_error("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
106-
return false;
107-
}
108-
for (; aligned_addr != end_addr; aligned_addr++)
109-
*(buf++) = *(ptr++);
78+
if (piod.piod_len < size) {
79+
print_error("ptrace(PT_IO, ..) failed to read %d bytes @ %lx, %d bytes read\n",
80+
size, addr, piod.piod_len);
81+
return false;
11082
}
83+
11184
return true;
11285
}
11386

@@ -121,7 +94,7 @@ static bool process_write_data(struct ps_prochandle* ph,
12194
static bool process_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwpid, struct reg *user) {
12295
// we have already attached to all thread 'pid's, just use ptrace call
12396
// to get regset now. Note that we don't cache regset upfront for processes.
124-
if (ptrace(PT_GETREGS, ph->pid, (caddr_t) user, 0) < 0) {
97+
if (ptrace(PT_GETREGS, lwpid, (caddr_t) user, 0) < 0) {
12598
print_error("ptrace(PTRACE_GETREGS, ...) failed for lwp %d (%d)\n", lwpid, ph->pid);
12699
return false;
127100
}

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@
3939

4040
class BsdCDebugger implements CDebugger {
4141
private BsdDebugger dbg;
42+
private boolean isDarwin; // variant for MacOS
4243

4344
BsdCDebugger(BsdDebugger dbg) {
4445
this.dbg = dbg;
46+
this.isDarwin = PlatformInfo.getOS().equals("darwin");
4547
}
4648

4749
public List<ThreadProxy> getThreadList() throws DebuggerException {
@@ -56,30 +58,46 @@ public LoadObject loadObjectContainingPC(Address pc) throws DebuggerException {
5658
if (pc == null) {
5759
return null;
5860
}
61+
5962
List<LoadObject> objs = getLoadObjectList();
60-
Object[] arr = objs.toArray();
61-
// load objects are sorted by base address, do binary search
62-
int mid = -1;
63-
int low = 0;
64-
int high = arr.length - 1;
63+
if (isDarwin) {
64+
Object[] arr = objs.toArray();
65+
// load objects are sorted by base address, do binary search
66+
int mid = -1;
67+
int low = 0;
68+
int high = arr.length - 1;
6569

66-
while (low <= high) {
67-
mid = (low + high) >> 1;
68-
LoadObject midVal = (LoadObject) arr[mid];
69-
long cmp = pc.minus(midVal.getBase());
70-
if (cmp < 0) {
71-
high = mid - 1;
72-
} else if (cmp > 0) {
73-
long size = midVal.getSize();
74-
if (cmp >= size) {
75-
low = mid + 1;
76-
} else {
77-
return (LoadObject) arr[mid];
78-
}
79-
} else { // match found
80-
return (LoadObject) arr[mid];
81-
}
70+
while (low <= high) {
71+
mid = (low + high) >> 1;
72+
LoadObject midVal = (LoadObject) arr[mid];
73+
long cmp = pc.minus(midVal.getBase());
74+
if (cmp < 0) {
75+
high = mid - 1;
76+
} else if (cmp > 0) {
77+
long size = midVal.getSize();
78+
if (cmp >= size) {
79+
low = mid + 1;
80+
} else {
81+
return (LoadObject) arr[mid];
82+
}
83+
} else { // match found
84+
return (LoadObject) arr[mid];
85+
}
86+
}
87+
} else {
88+
/* Typically we have about ten loaded objects here. So no reason to do
89+
sort/binary search here. Linear search gives us acceptable performance.
90+
This also works more reliably on BSD.*/
91+
for (int i = 0; i < objs.size(); i++) {
92+
LoadObject ob = objs.get(i);
93+
Address base = ob.getBase();
94+
long size = ob.getSize();
95+
if (pc.greaterThanOrEqual(base) && pc.lessThan(base.addOffsetTo(size))) {
96+
return ob;
97+
}
98+
}
8299
}
100+
83101
// no match found.
84102
return null;
85103
}

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,12 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
8080
// loadObjectList is filled by attach0 method
8181
private List<LoadObject> loadObjectList;
8282

83+
// MacOS code uses this thread list
8384
private List<JavaThread> javaThreadList;
8485

86+
// BSD code uses this thread list
87+
private List<ThreadProxy> threadList;
88+
8589
// called by native method lookupByAddress0
8690
private ClosestSymbol createClosestSymbol(String name, long offset) {
8791
return new ClosestSymbol(name, offset);
@@ -272,6 +276,7 @@ private void fillJavaThreadList() {
272276
public synchronized void attach(int processID) throws DebuggerException {
273277
checkAttached();
274278
loadObjectList = new ArrayList<>();
279+
threadList = new ArrayList<>();
275280
class AttachTask implements WorkerThreadTask {
276281
int pid;
277282
public void doit(BsdDebuggerLocal debugger) {
@@ -291,6 +296,7 @@ public void doit(BsdDebuggerLocal debugger) {
291296
public synchronized void attach(String execName, String coreName) {
292297
checkAttached();
293298
loadObjectList = new ArrayList<>();
299+
threadList = new ArrayList<>();
294300
attach0(execName, coreName);
295301
attached = true;
296302
isCore = true;
@@ -303,6 +309,7 @@ public synchronized boolean detach() {
303309
return false;
304310
}
305311

312+
threadList = null;
306313
javaThreadList = null;
307314
loadObjectList = null;
308315

0 commit comments

Comments
 (0)