/** * Create the VMThrowable * * @return constructed VMThrowable */ static VMThrowable fillInStackTrace(Throwable parent) { if (!VM.fullyBooted) { return null; } else if (RVMThread.getCurrentThread().isCollectorThread()) { VM.sysWriteln("Exception in GC thread"); RVMThread.dumpVirtualMachine(); return null; } try { StackTrace stackTrace = new StackTrace(); return new VMThrowable(stackTrace); } catch (OutOfMemoryError oome) { return null; } catch (Throwable t) { VM.sysFail( "VMThrowable.fillInStackTrace(): Cannot fill in a stack trace; got a weird Throwable when I tried to"); return null; } }
/** * Get return address for a frame in a specific thread * * @param fp its frame pointer * @param thread the thread whose stack is being examined */ @Uninterruptible public static Address getReturnAddress(Address fp, RVMThread thread) { Address ip = getReturnAddressLocation(fp).loadAddress(); if (RVMThread.isTrampolineIP(ip)) return thread.getTrampolineHijackedReturnAddress(); else return ip; }
/** * Get return address for a frame in the current thread * * @param fp its frame pointer */ @Uninterruptible public static Address getReturnAddress(Address fp) { return getReturnAddress(fp, RVMThread.getCurrentThread()); }
/** * Get return address for a frame in a case where the frame is known not to be a trampoline frame. * * @param fp its frame pointer */ @Uninterruptible public static Address getReturnAddressUnchecked(Address fp) { Address ip = getReturnAddressLocation(fp).loadAddress(); if (VM.VerifyAssertions) VM._assert(!RVMThread.isTrampolineIP(ip)); return ip; }
/** * Dump all threads & their stacks starting at the frame identified by the threads saved * contextRegisters (ip & fp fields). */ @Uninterruptible public static void dumpAllThreadStacks() { RVMThread.dumpVirtualMachine(); } // dumpAllThreadStacks
/** Return the stack trace */ StackTraceElement[] getStackTrace(Throwable parent) { if (stackTrace == null) { return zeroLengthStackTrace; } else if (RVMThread.getCurrentThread().isCollectorThread()) { VM.sysWriteln( "VMThrowable.getStackTrace called from GC thread: dumping stack using scheduler"); RVMThread.dumpStack(); return zeroLengthStackTrace; } StackTrace.Element[] vmElements; try { vmElements = stackTrace.getStackTrace(parent); } catch (Throwable t) { VM.sysWriteln("Error calling StackTrace.getStackTrace: dumping stack using scheduler"); RVMThread.dumpStack(); return zeroLengthStackTrace; } if (vmElements == null) { VM.sysWriteln("Error calling StackTrace.getStackTrace returned null"); RVMThread.dumpStack(); return zeroLengthStackTrace; } if (VM.fullyBooted) { try { StackTraceElement[] elements = new StackTraceElement[vmElements.length]; for (int i = 0; i < vmElements.length; i++) { StackTrace.Element vmElement = vmElements[i]; String fileName = vmElement.getFileName(); int lineNumber = vmElement.getLineNumber(); String className = vmElement.getClassName(); String methodName = vmElement.getMethodName(); boolean isNative = vmElement.isNative(); elements[i] = new StackTraceElement(fileName, lineNumber, className, methodName, isNative); } return elements; } catch (Throwable t) { VM.sysWriteln("Error constructing StackTraceElements: dumping stack"); } } else { VM.sysWriteln("Dumping stack using sysWrite in not fullyBooted VM"); } for (StackTrace.Element vmElement : vmElements) { if (vmElement == null) { VM.sysWriteln("Error stack trace with null entry"); RVMThread.dumpStack(); return zeroLengthStackTrace; } String fileName = vmElement.getFileName(); int lineNumber = vmElement.getLineNumber(); String className = vmElement.getClassName(); String methodName = vmElement.getMethodName(); VM.sysWrite(" at "); if (!className.isEmpty()) { VM.sysWrite(className); VM.sysWrite("."); } VM.sysWrite(methodName); if (fileName != null) { VM.sysWrite("("); VM.sysWrite(fileName); if (lineNumber > 0) { VM.sysWrite(":"); VM.sysWrite(vmElement.getLineNumber()); } VM.sysWrite(")"); } VM.sysWriteln(); } return zeroLengthStackTrace; }