/** 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; }
public void resume() { switch (suspendPolicy()) { case EventRequest.SUSPEND_ALL: vm.resume(); break; case EventRequest.SUSPEND_EVENT_THREAD: ThreadReference thread = eventThread(); if (thread == null) { throw new InternalException("Inconsistent suspend policy"); } thread.resume(); break; case EventRequest.SUSPEND_NONE: // Do nothing break; default: throw new InternalException("Invalid suspend policy"); } }
/** 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; }
public void breakpointReached(BreakpointEvent event) { String origMethodName = event.location().method().name(); String methodName = origMethodName.substring(2); ThreadReference tr = event.thread(); if (vm().canForceEarlyReturn()) { try { if ("bytef".equals(methodName)) { Field theValueField = targetClass.fieldByName("ebyteValue"); ByteValue theValue = (ByteValue) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); /* * See what happens if we access the stack after the force * and before the resume. Disabling this since spec says * the stack is undefined. This type of code can be used to * pursue just what that means. * * StackFrame sf = tr.frame(0); * List<Value> ll = sf.getArgumentValues(); * for (Value vv: ll) { * System.out.println("vv = " + vv); * } */ } else if ("charf".equals(methodName)) { Field theValueField = targetClass.fieldByName("echarValue"); CharValue theValue = (CharValue) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("doublef".equals(methodName)) { Field theValueField = targetClass.fieldByName("edoubleValue"); DoubleValue theValue = (DoubleValue) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("floatf".equals(methodName)) { Field theValueField = targetClass.fieldByName("efloatValue"); FloatValue theValue = (FloatValue) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("intf".equals(methodName)) { Field theValueField = targetClass.fieldByName("eintValue"); IntegerValue theValue = (IntegerValue) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("longf".equals(methodName)) { Field theValueField = targetClass.fieldByName("elongValue"); LongValue theValue = (LongValue) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("shortf".equals(methodName)) { Field theValueField = targetClass.fieldByName("eshortValue"); ShortValue theValue = (ShortValue) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("booleanf".equals(methodName)) { Field theValueField = targetClass.fieldByName("ebooleanValue"); BooleanValue theValue = (BooleanValue) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("stringf".equals(methodName)) { Field theValueField = targetClass.fieldByName("estringValue"); StringReference theValue = (StringReference) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("classf".equals(methodName)) { Field theValueField = targetClass.fieldByName("eclassValue"); ClassObjectReference theValue = (ClassObjectReference) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("classLoaderf".equals(methodName)) { Field theValueField = targetClass.fieldByName("eclassLoaderValue"); ClassLoaderReference theValue = (ClassLoaderReference) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("threadf".equals(methodName)) { Field theValueField = targetClass.fieldByName("ethreadValue"); ThreadReference theValue = (ThreadReference) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("threadGroupf".equals(methodName)) { Field theValueField = targetClass.fieldByName("ethreadGroupValue"); ThreadGroupReference theValue = (ThreadGroupReference) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("intArrayf".equals(methodName)) { Field theValueField = targetClass.fieldByName("eintArrayValue"); ArrayReference theValue = (ArrayReference) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("nullObjectf".equals(methodName)) { tr.forceEarlyReturn(null); } else if ("objectf".equals(methodName)) { Field theValueField = targetClass.fieldByName("eobjectValue"); ObjectReference theValue = (ObjectReference) targetClass.getValue(theValueField); tr.forceEarlyReturn(theValue); } else if ("voidf".equals(methodName)) { VoidValue theValue = vm().mirrorOfVoid(); tr.forceEarlyReturn(theValue); } else { failure("failure: Unknown methodName: " + origMethodName); } } catch (Exception ex) { failure("failure: " + ex.toString()); ex.printStackTrace(); } } else { System.out.println("Cannot force early return for method: " + origMethodName); } }
/* * Complete the construction of an EventSet. This is called from * an event handler thread. It upacks the JDWP events inside * the packet and creates EventImpls for them. The EventSet is already * on EventQueues when this is called, so it has to be synch. */ synchronized void build() { if (pkt == null) { return; } PacketStream ps = new PacketStream(vm, pkt); JDWP.Event.Composite compEvt = new JDWP.Event.Composite(vm, ps); suspendPolicy = compEvt.suspendPolicy; if ((vm.traceFlags & vm.TRACE_EVENTS) != 0) { switch (suspendPolicy) { case JDWP.SuspendPolicy.ALL: vm.printTrace("EventSet: SUSPEND_ALL"); break; case JDWP.SuspendPolicy.EVENT_THREAD: vm.printTrace("EventSet: SUSPEND_EVENT_THREAD"); break; case JDWP.SuspendPolicy.NONE: vm.printTrace("EventSet: SUSPEND_NONE"); break; } } ThreadReference fix6485605 = null; for (int i = 0; i < compEvt.events.length; i++) { EventImpl evt = createEvent(compEvt.events[i]); if ((vm.traceFlags & vm.TRACE_EVENTS) != 0) { try { vm.printTrace("Event: " + evt); } catch (VMDisconnectedException ee) { // ignore - see bug 6502716 } } switch (evt.destination()) { case UNKNOWN_EVENT: // Ignore disabled, deleted, unknown events, but // save the thread if there is one since we might // have to resume it. Note that events for different // threads can't be in the same event set. if (evt instanceof ThreadedEventImpl && suspendPolicy == JDWP.SuspendPolicy.EVENT_THREAD) { fix6485605 = ((ThreadedEventImpl) evt).thread(); } continue; case CLIENT_EVENT: addEvent(evt); break; case INTERNAL_EVENT: if (internalEventSet == null) { internalEventSet = new EventSetImpl(this.vm, null); } internalEventSet.addEvent(evt); break; default: throw new InternalException("Invalid event destination"); } } pkt = null; // No longer needed - free it up // Avoid hangs described in 6296125, 6293795 if (super.size() == 0) { // This set has no client events. If we don't do // needed resumes, no one else is going to. if (suspendPolicy == JDWP.SuspendPolicy.ALL) { vm.resume(); } else if (suspendPolicy == JDWP.SuspendPolicy.EVENT_THREAD) { // See bug 6485605. if (fix6485605 != null) { fix6485605.resume(); } else { // apparently, there is nothing to resume. } } suspendPolicy = JDWP.SuspendPolicy.NONE; } }
public String toString() { return eventName() + " in thread " + thread.name(); }