@Override public String getEventMessage(LocatableEvent event) { final Location location = event.location(); String sourceName; try { sourceName = location.sourceName(); } catch (AbsentInformationException e) { sourceName = getFileName(); } final boolean printFullTrace = Registry.is("debugger.breakpoint.message.full.trace"); StringBuilder builder = new StringBuilder(); if (printFullTrace) { builder.append( DebuggerBundle.message( "status.line.breakpoint.reached.full.trace", DebuggerUtilsEx.getLocationMethodQName(location))); try { final List<StackFrame> frames = event.thread().frames(); renderTrace(frames, builder); } catch (IncompatibleThreadStateException e) { builder.append("Stacktrace not available: ").append(e.getMessage()); } } else { builder.append( DebuggerBundle.message( "status.line.breakpoint.reached", DebuggerUtilsEx.getLocationMethodQName(location), sourceName, getLineIndex() + 1)); } return builder.toString(); }
protected StackFrame getStackFrame() { try { if (this.breakpointLine == Integer.MAX_VALUE) { return this.jdiThread.frame(1); } return this.jdiThread.frame(0); } catch (IncompatibleThreadStateException e) { e.printStackTrace(); 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; }
public boolean run(String codeSnippetClassName) { ClassType codeSnippetClass; ObjectReference codeSnippet; Method method; List arguments; ObjectReference codeSnippetRunner; try { // Get the code snippet class List classes = jdiVM.classesByName(codeSnippetClassName); while (classes.size() == 0) { try { Thread.sleep(100); } catch (InterruptedException e) { } classes = jdiVM.classesByName(codeSnippetClassName); if (classes.size() == 0) { // workaround bug in Standard VM Iterator iterator = this.jdiVM.allClasses().iterator(); while (iterator.hasNext()) { ReferenceType type = (ReferenceType) iterator.next(); if (type.name().equals(codeSnippetClassName)) { classes = new ArrayList(1); classes.add(type); break; } } } } codeSnippetClass = (ClassType) classes.get(0); // Create a new code snippet Method constructor = (Method) codeSnippetClass.methodsByName("<init>").get(0); codeSnippet = codeSnippetClass.newInstance( jdiThread, constructor, new ArrayList(), ClassType.INVOKE_SINGLE_THREADED); // Install local variables and "this" into generated fields StackFrame stackFrame = getStackFrame(); try { Iterator variables = stackFrame.visibleVariables().iterator(); while (variables.hasNext()) { LocalVariable jdiVariable = (LocalVariable) variables.next(); Value value = stackFrame.getValue(jdiVariable); Field field = codeSnippetClass.fieldByName(new String(LOCAL_VAR_PREFIX) + jdiVariable.name()); codeSnippet.setValue(field, value); } } catch (AbsentInformationException e) { // No variables } Field delegateThis = codeSnippetClass.fieldByName(new String(DELEGATE_THIS)); ObjectReference thisObject; if (delegateThis != null && ((thisObject = stackFrame.thisObject()) != null)) { codeSnippet.setValue(delegateThis, thisObject); } // Get the code snippet runner ClassType codeSnippetRunnerClass = (ClassType) jdiVM.classesByName(CODE_SNIPPET_RUNNER_CLASS_NAME).get(0); Field theRunner = codeSnippetRunnerClass.fieldByName(THE_RUNNER_FIELD); codeSnippetRunner = (ObjectReference) codeSnippetRunnerClass.getValue(theRunner); // Get the method 'runCodeSnippet' and its arguments method = (Method) codeSnippetRunnerClass.methodsByName(RUN_CODE_SNIPPET_METHOD).get(0); arguments = new ArrayList(); arguments.add(codeSnippet); } catch (ClassNotLoadedException e) { e.printStackTrace(); return false; } catch (IncompatibleThreadStateException e) { e.printStackTrace(); return false; } catch (InvalidTypeException e) { e.printStackTrace(); return false; } catch (InvocationException e) { e.printStackTrace(); return false; } try { // Invoke runCodeSnippet(CodeSnippet) codeSnippetRunner.invokeMethod( jdiThread, method, arguments, ClassType.INVOKE_SINGLE_THREADED); // Retrieve values of local variables and put them back in the stack frame StackFrame stackFrame = getStackFrame(); try { Iterator variables = stackFrame.visibleVariables().iterator(); while (variables.hasNext()) { LocalVariable jdiVariable = (LocalVariable) variables.next(); Field field = codeSnippetClass.fieldByName(new String(LOCAL_VAR_PREFIX) + jdiVariable.name()); Value value = codeSnippet.getValue(field); stackFrame.setValue(jdiVariable, value); } } catch (AbsentInformationException e) { // No variables } } catch (ClassNotLoadedException e) { e.printStackTrace(); } catch (IncompatibleThreadStateException e) { e.printStackTrace(); } catch (InvalidTypeException e) { e.printStackTrace(); } catch (InvocationException e) { e.printStackTrace(); } return true; }