@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(); }
/** * 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; }