// we set an observer to detect VirtualMachineImpl.dispose call // and on dispose we add corresponding VirtualMachineImpl.class to // free VirtualMachimeImpl Class list. protected static void setVMDisposeObserver(final Object vm) { try { Method setDisposeObserverMethod = vm.getClass() .getDeclaredMethod("setDisposeObserver", new Class[] {java.util.Observer.class}); setDisposeObserverMethod.setAccessible(true); setDisposeObserverMethod.invoke( vm, new Object[] { new Observer() { public void update(Observable o, Object data) { if (DEBUG) { System.out.println("got VM.dispose notification"); } addFreeVMImplClass(vm.getClass()); } } }); } catch (Exception exp) { if (DEBUG) { System.out.println("setVMDisposeObserver() got an exception:"); exp.printStackTrace(); } } }
public VirtualMachine attach(Map arguments) throws IOException, IllegalConnectorArgumentsException { int pid = 0; try { pid = Integer.parseInt(argument(ARG_PID, arguments).value()); } catch (NumberFormatException nfe) { throw (IllegalConnectorArgumentsException) new IllegalConnectorArgumentsException(nfe.getMessage(), ARG_PID).initCause(nfe); } checkProcessAttach(pid); VirtualMachine myVM = null; try { try { Class vmImplClass = loadVirtualMachineImplClass(); myVM = createVirtualMachine(vmImplClass, pid); } catch (InvocationTargetException ite) { Class vmImplClass = handleVMVersionMismatch(ite); if (vmImplClass != null) { return createVirtualMachine(vmImplClass, pid); } else { throw ite; } } } catch (Exception ee) { if (DEBUG) { System.out.println("VirtualMachineImpl() got an exception:"); ee.printStackTrace(); System.out.println("pid = " + pid); } throw (IOException) new IOException().initCause(ee); } setVMDisposeObserver(myVM); return myVM; }
/** * If the causal chain has a sun.jvm.hotspot.runtime.VMVersionMismatchException, attempt to load * VirtualMachineImpl class for target VM version. */ protected static Class handleVMVersionMismatch(InvocationTargetException ite) { Throwable cause = ite.getCause(); if (DEBUG) { System.out.println("checking for version mismatch..."); } while (cause != null) { try { if (isVMVersionMismatch(cause)) { if (DEBUG) { System.out.println("Triggering cross VM version support..."); } return loadVirtualMachineImplClass(getVMVersion(cause)); } } catch (Exception exp) { if (DEBUG) { System.out.println("failed to load VirtualMachineImpl class"); exp.printStackTrace(); } return null; } cause = cause.getCause(); } return null; }
/** * Move through a list of stack frames, searching for references to code found in the current * sketch. Return with a RunnerException that contains the location of the error, or if nothing is * found, just return with a RunnerException that wraps the error message itself. */ protected SketchException findException( String message, ObjectReference or, ThreadReference thread) { try { // use to dump the stack for debugging // for (StackFrame frame : thread.frames()) { // System.out.println("frame: " + frame); // } List<StackFrame> frames = thread.frames(); for (StackFrame frame : frames) { try { Location location = frame.location(); String filename = null; filename = location.sourceName(); int lineNumber = location.lineNumber() - 1; SketchException rex = build.placeException(message, filename, lineNumber); if (rex != null) { return rex; } } catch (AbsentInformationException e) { // Any of the thread.blah() methods can throw an AbsentInformationEx // if that bit of data is missing. If so, just write out the error // message to the console. // e.printStackTrace(); // not useful exception = new SketchException(message); exception.hideStackTrace(); listener.statusError(exception); } } } catch (IncompatibleThreadStateException e) { // This shouldn't happen, but if it does, print the exception in case // it's something that needs to be debugged separately. e.printStackTrace(); } // before giving up, try to extract from the throwable object itself // since sometimes exceptions are re-thrown from a different context try { // assume object reference is Throwable, get stack trace Method method = ((ClassType) or.referenceType()) .concreteMethodByName("getStackTrace", "()[Ljava/lang/StackTraceElement;"); ArrayReference result = (ArrayReference) or.invokeMethod( thread, method, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED); // iterate through stack frames and pull filename and line number for each for (Value val : result.getValues()) { ObjectReference ref = (ObjectReference) val; method = ((ClassType) ref.referenceType()) .concreteMethodByName("getFileName", "()Ljava/lang/String;"); StringReference strref = (StringReference) ref.invokeMethod( thread, method, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED); String filename = strref == null ? "Unknown Source" : strref.value(); method = ((ClassType) ref.referenceType()).concreteMethodByName("getLineNumber", "()I"); IntegerValue intval = (IntegerValue) ref.invokeMethod( thread, method, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED); int lineNumber = intval.intValue() - 1; SketchException rex = build.placeException(message, filename, lineNumber); if (rex != null) { return rex; } } // for (Method m : ((ClassType) or.referenceType()).allMethods()) { // System.out.println(m + " | " + m.signature() + " | " + m.genericSignature()); // } // Implemented for 2.0b9, writes a stack trace when there's an internal error inside core. method = ((ClassType) or.referenceType()).concreteMethodByName("printStackTrace", "()V"); // System.err.println("got method " + method); or.invokeMethod( thread, method, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED); } catch (Exception e) { e.printStackTrace(); } // Give up, nothing found inside the pile of stack frames SketchException rex = new SketchException(message); // exception is being created /here/, so stack trace is not useful rex.hideStackTrace(); return rex; }