6620329: jstack prints double native methods on Solaris/sparc
Fixed stack walking code in sparc to start frame walk from last_java_sp. Reviewed-by: sgoldman
This commit is contained in:
parent
d69fdc9d5b
commit
510a97ebed
@ -316,6 +316,14 @@ public class ObjectHeap {
|
||||
iterateLiveRegions(liveRegions, visitor, null);
|
||||
}
|
||||
|
||||
public boolean isValidMethod(OopHandle handle) {
|
||||
OopHandle klass = Oop.getKlassForOopHandle(handle);
|
||||
if (klass != null && klass.equals(methodKlassHandle)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Creates an instance from the Oop hierarchy based based on the handle
|
||||
public Oop newOop(OopHandle handle) {
|
||||
// The only known way to detect the right type of an oop is
|
||||
@ -375,8 +383,10 @@ public class ObjectHeap {
|
||||
}
|
||||
}
|
||||
|
||||
System.err.println("Unknown oop at " + handle);
|
||||
System.err.println("Oop's klass is " + klass);
|
||||
if (DEBUG) {
|
||||
System.err.println("Unknown oop at " + handle);
|
||||
System.err.println("Oop's klass is " + klass);
|
||||
}
|
||||
|
||||
throw new UnknownOopException();
|
||||
}
|
||||
|
@ -215,11 +215,11 @@ public class JavaThread extends Thread {
|
||||
if (f == null) return null;
|
||||
boolean imprecise = true;
|
||||
if (f.isInterpretedFrame() && !f.isInterpretedFrameValid()) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Correcting for invalid interpreter frame");
|
||||
}
|
||||
f = f.sender(regMap);
|
||||
imprecise = false;
|
||||
if (DEBUG) {
|
||||
System.out.println("Correcting for invalid interpreter frame");
|
||||
}
|
||||
f = f.sender(regMap);
|
||||
imprecise = false;
|
||||
}
|
||||
VFrame vf = VFrame.newVFrame(f, regMap, this, true, imprecise);
|
||||
if (vf == null) {
|
||||
@ -228,10 +228,7 @@ public class JavaThread extends Thread {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (vf.isJavaFrame()) {
|
||||
return (JavaVFrame) vf;
|
||||
}
|
||||
return (JavaVFrame) vf.javaSender();
|
||||
return vf.isJavaFrame() ? (JavaVFrame)vf : vf.javaSender();
|
||||
}
|
||||
|
||||
/** In this system, a JavaThread is the top-level factory for a
|
||||
|
@ -121,6 +121,13 @@ public class SolarisSPARCJavaThreadPDAccess implements JavaThreadPDAccess {
|
||||
}
|
||||
|
||||
public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
|
||||
|
||||
// If java stack is walkable then both last_Java_sp and last_Java_pc are
|
||||
// non null and we can start stack walk from this frame.
|
||||
if (thread.getLastJavaSP() != null && thread.getLastJavaPC() != null) {
|
||||
return new SPARCFrame(SPARCFrame.biasSP(thread.getLastJavaSP()), thread.getLastJavaPC());
|
||||
}
|
||||
|
||||
ThreadProxy t = getThreadProxy(addr);
|
||||
SPARCThreadContext context = (SPARCThreadContext) t.getContext();
|
||||
// For now, let's see what happens if we do a similar thing to
|
||||
|
@ -422,6 +422,13 @@ public class SPARCFrame extends Frame {
|
||||
if (getFP().addOffsetTo(INTERPRETER_FRAME_VM_LOCAL_WORDS * VM.getVM().getAddressSize()).lessThan(getSP())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OopHandle methodHandle = addressOfInterpreterFrameMethod().getOopHandleAt(0);
|
||||
|
||||
if (VM.getVM().getObjectHeap().isValidMethod(methodHandle) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// These are hacks to keep us out of trouble.
|
||||
// The problem with these is that they mask other problems
|
||||
if (getFP().lessThanOrEqual(getSP())) { // this attempts to deal with unsigned comparison above
|
||||
@ -433,9 +440,18 @@ public class SPARCFrame extends Frame {
|
||||
// FIXME: this is not atomic with respect to GC and is unsuitable
|
||||
// for use in a non-debugging, or reflective, system. Need to
|
||||
// figure out how to express this.
|
||||
if (addressOfInterpreterFrameBCX().getAddressAt(0) == null) {
|
||||
return false; // BCP not yet set up
|
||||
Address bcx = addressOfInterpreterFrameBCX().getAddressAt(0);
|
||||
|
||||
Method method;
|
||||
try {
|
||||
method = (Method) VM.getVM().getObjectHeap().newOop(methodHandle);
|
||||
} catch (UnknownOopException ex) {
|
||||
return false;
|
||||
}
|
||||
int bci = bcpToBci(bcx, method);
|
||||
//validate bci
|
||||
if (bci < 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -471,7 +487,7 @@ public class SPARCFrame extends Frame {
|
||||
// will update it accordingly
|
||||
map.setIncludeArgumentOops(false);
|
||||
|
||||
if (cb == null && isEntryFrame()) {
|
||||
if (isEntryFrame()) {
|
||||
return senderForEntryFrame(map);
|
||||
}
|
||||
|
||||
@ -539,7 +555,6 @@ public class SPARCFrame extends Frame {
|
||||
int SP_OFFSET_IN_GREGSET = 17;
|
||||
raw_sp = fp.getAddressAt(VM.getVM().getAddressSize() * SP_OFFSET_IN_GREGSET);
|
||||
Address pc = fp.getAddressAt(VM.getVM().getAddressSize() * PC_OFFSET_IN_GREGSET);
|
||||
// System.out.println(" next frame's SP: " + sp + " PC: " + pc);
|
||||
return new SPARCFrame(raw_sp, pc);
|
||||
}
|
||||
}
|
||||
@ -562,10 +577,8 @@ public class SPARCFrame extends Frame {
|
||||
// sender's _interpreter_sp_adjustment field.
|
||||
if (VM.getVM().getInterpreter().contains(pc)) {
|
||||
isInterpreted = true;
|
||||
if (VM.getVM().isClientCompiler()) {
|
||||
map.makeIntegerRegsUnsaved();
|
||||
map.shiftWindow(sp, youngerSP);
|
||||
}
|
||||
map.makeIntegerRegsUnsaved();
|
||||
map.shiftWindow(sp, youngerSP);
|
||||
} else {
|
||||
// Find a CodeBlob containing this frame's pc or elide the lookup and use the
|
||||
// supplied blob which is already known to be associated with this frame.
|
||||
|
@ -87,12 +87,13 @@ public class PStack extends Tool {
|
||||
while (f != null) {
|
||||
ClosestSymbol sym = f.closestSymbolToPC();
|
||||
Address pc = f.pc();
|
||||
out.print(pc + "\t");
|
||||
if (sym != null) {
|
||||
String name = sym.getName();
|
||||
if (cdbgCanDemangle) {
|
||||
name = cdbg.demangle(name);
|
||||
}
|
||||
out.print(pc + "\t" + name);
|
||||
out.print(name);
|
||||
long diff = sym.getOffset();
|
||||
if (diff != 0L) {
|
||||
out.print(" + 0x" + Long.toHexString(diff));
|
||||
@ -120,7 +121,6 @@ public class PStack extends Tool {
|
||||
// look for known code blobs
|
||||
CodeCache c = VM.getVM().getCodeCache();
|
||||
if (c.contains(pc)) {
|
||||
out.print(pc + "\t");
|
||||
CodeBlob cb = c.findBlobUnsafe(pc);
|
||||
if (cb.isNMethod()) {
|
||||
names = getJavaNames(th, f.localVariableBase());
|
||||
@ -144,18 +144,18 @@ public class PStack extends Tool {
|
||||
out.println("<Unknown code blob>");
|
||||
}
|
||||
} else {
|
||||
printUnknown(out,pc);
|
||||
printUnknown(out);
|
||||
}
|
||||
}
|
||||
// print java frames, if any
|
||||
if (names != null && names.length != 0) {
|
||||
// print java frame(s)
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
out.println(pc + "\t" + names[i]);
|
||||
out.println(names[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printUnknown(out,pc);
|
||||
printUnknown(out);
|
||||
}
|
||||
}
|
||||
f = f.sender();
|
||||
@ -220,8 +220,8 @@ public class PStack extends Tool {
|
||||
}
|
||||
}
|
||||
|
||||
private void printUnknown(PrintStream out, Address pc) {
|
||||
out.println(pc + "\t????????");
|
||||
private void printUnknown(PrintStream out) {
|
||||
out.println("\t????????");
|
||||
}
|
||||
|
||||
private String[] getJavaNames(ThreadProxy th, Address fp) {
|
||||
|
Loading…
Reference in New Issue
Block a user