static synchronized String sourceLine(Location location, int lineNumber) throws IOException { if (lineNumber == -1) { throw new IllegalArgumentException(); } try { String fileName = location.sourceName(); Iterator<SourceCode> iter = sourceCache.iterator(); SourceCode code = null; while (iter.hasNext()) { SourceCode candidate = iter.next(); if (candidate.fileName().equals(fileName)) { code = candidate; iter.remove(); break; } } if (code == null) { BufferedReader reader = sourceReader(location); if (reader == null) { throw new FileNotFoundException(fileName); } code = new SourceCode(fileName, reader); if (sourceCache.size() == SOURCE_CACHE_SIZE) { sourceCache.remove(sourceCache.size() - 1); } } sourceCache.add(0, code); return code.sourceLine(lineNumber); } catch (AbsentInformationException e) { throw new IllegalArgumentException(); } }
/** if this line can not be current => stepOver & return true. return false on the other hand. */ boolean resolveCanBeCurrent(ThreadReference tr) { try { Location l = tr.frame(0).location(); if (l == null) return false; return resolveCanBeCurrent( tr, Utils.getLineForSource(l.declaringType().name(), l.sourceName(), l.lineNumber())); } catch (Exception e) { } return false; }
private void dumpStack(ThreadReference thread, boolean showPC) { // ### Check for these. // env.failure("Thread no longer exists."); // env.failure("Target VM must be in interrupted state."); // env.failure("Current thread isn't suspended."); // ### Should handle extremely long stack traces sensibly for user. List<StackFrame> stack = null; try { stack = thread.frames(); } catch (IncompatibleThreadStateException e) { env.failure("Thread is not suspended."); } // ### Fix this! // ### Previously mishandled cases where thread was not current. // ### Now, prints all of the stack regardless of current frame. int frameIndex = 0; // int frameIndex = context.getCurrentFrameIndex(); if (stack == null) { env.failure("Thread is not running (no stack)."); } else { OutputSink out = env.getOutputSink(); int nFrames = stack.size(); for (int i = frameIndex; i < nFrames; i++) { StackFrame frame = stack.get(i); Location loc = frame.location(); Method meth = loc.method(); out.print(" [" + (i + 1) + "] "); out.print(meth.declaringType().name()); out.print('.'); out.print(meth.name()); out.print(" ("); if (meth.isNative()) { out.print("native method"); } else if (loc.lineNumber() != -1) { try { out.print(loc.sourceName()); } catch (AbsentInformationException e) { out.print("<unknown>"); } out.print(':'); out.print(loc.lineNumber()); } out.print(')'); if (showPC) { long pc = loc.codeIndex(); if (pc != -1) { out.print(", pc = " + pc); } } out.println(); } out.show(); } }
/** Executes breakpoint hit event. */ public void exec(com.sun.jdi.event.Event ev) { // S ystem.out.println ("exec "); // NOI18N removeStepRequest(); StepEvent event = (StepEvent) ev; ThreadReference tr = event.thread(); Location loc = event.location(); int ln = -1; String methodName = "?"; // NOI18N String className = "?"; // NOI18N String lineNumber = "?"; // NOI18N String threadName = tr.name(); Line l = null; if (loc != null) { if (loc.method() != null) methodName = loc.method().name(); className = loc.declaringType().name(); ln = loc.lineNumber(); if (ln >= 0) lineNumber = "" + loc.lineNumber(); } if (ln != -1) try { l = Utils.getLineForSource(className, loc.sourceName(), ln); } catch (AbsentInformationException e) { l = Utils.getLine(className, ln); } if (resolveCanBeCurrent(tr, l)) // if this line can not be current resolveCanBeCurrent () calls stepOver return; // line can be current if ((l == null) && (getLastAction() == ACTION_TRACE_INTO)) // try to find another "intelligent" line of code traceToSourceCode(tr); // you know - intelligent means that one with source code else { makeCurrent(threadName, className, methodName, lineNumber, l != null, tr); operator.stopRequest(); } }
/** * 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; }