@Override public List<IWatchable> getVisibleWatchables() { try { StackFrame stackFrame = getStackFrame(); List<IWatchable> result = new ArrayList<IWatchable>(); if (stackFrame != null) { for (LocalVariable variable : stackFrame.visibleVariables()) { result.add(new JavaLocalVariable(variable, this, myClassFqName, myThreadReference)); } ObjectReference thisObject = stackFrame.thisObject(); if (thisObject != null) { result.add(new JavaThisObject(thisObject, this, myClassFqName, myThreadReference)); } else { result.add( new JavaStaticContext( getStackFrame().location().declaringType(), myClassFqName, myThreadReference)); } } return result; } catch (InvalidStackFrameException ex) { LOG.warning( "InvalidStackFrameException", ex); // TODO something should be done here. See, for instance, how idea deals with those // exceptions return Collections.emptyList(); } catch (AbsentInformationException ex) { // doing nothing, variables are just not available for us return Collections.emptyList(); } }
public char[] declaringTypeName() { if (this.breakpointLine != Integer.MAX_VALUE) { // if not in a code snippet StackFrame frame = getStackFrame(); return frame.location().declaringType().name().toCharArray(); } return null; }
@Override public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { // ### We should indicate the current thread independently of the // ### selection, e.g., with an icon, because the user may change // ### the selection graphically without affecting the current // ### thread. super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value == null) { this.setText("<unavailable>"); } else { StackFrame frame = (StackFrame) value; Location loc = frame.location(); Method meth = loc.method(); String methName = meth.declaringType().name() + '.' + meth.name(); String position = ""; if (meth.isNative()) { position = " (native method)"; } else if (loc.lineNumber() != -1) { position = ":" + loc.lineNumber(); } else { long pc = loc.codeIndex(); if (pc != -1) { position = ", pc = " + pc; } } // Indices are presented to the user starting from 1, not 0. this.setText("[" + (index + 1) + "] " + methName + position); } return this; }
public boolean isStatic() { if (this.breakpointLine != Integer.MAX_VALUE) { // if not in a code snippet StackFrame frame = getStackFrame(); return frame.location().method().isStatic(); } return false; }
public Value getLocalVariableValue(StackFrame fr, String localName) throws AbsentInformationException, IncompatibleThreadStateException { Value ret = null; LocalVariable var = fr.visibleVariableByName(localName); if (var != null) { ret = fr.getValue(var); } return ret; }
public List<LocalVariable> getLocals(ThreadReference tr, int idx) throws IllegalArgumentException, IncompatibleThreadStateException, AbsentInformationException { StackFrame frame = tr.frames().get(idx); if (frame != null) { return frame.visibleVariables(); } return null; }
public Value getLocalVariableValue(ThreadReference tr, int frameIdx, String localName) throws AbsentInformationException, IncompatibleThreadStateException { StackFrame fr = tr.frame(frameIdx); Value ret = null; LocalVariable var = fr.visibleVariableByName(localName); if (var != null) { ret = fr.getValue(var); } return ret; }
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(); } }
protected void runTests() throws Exception { /* * Get to the top of main() * to determine targetClass and mainThread */ BreakpointEvent bpe = startToMain("GetLocalVariables2Targ"); targetClass = bpe.location().declaringType(); mainThread = bpe.thread(); EventRequestManager erm = vm().eventRequestManager(); bpe = resumeTo("GetLocalVariables2Targ", "bar", "(I)Z"); /* * Inspect the stack frame for main(), not bar()... */ StackFrame frame = bpe.thread().frame(1); List localVars = frame.visibleVariables(); System.out.println(" Visible variables at this point are: "); for (Iterator it = localVars.iterator(); it.hasNext(); ) { LocalVariable lv = (LocalVariable) it.next(); System.out.print(lv.name()); System.out.print(" typeName: "); System.out.print(lv.typeName()); System.out.print(" signature: "); System.out.print(lv.type().signature()); System.out.print(" primitive type: "); System.out.println(lv.type().name()); if ("command".equals(lv.name())) { failure("Failure: LocalVariable \"command\" should not be visible at this point."); if (lv.isVisible(frame)) { System.out.println("Failure: \"command.isvisible(frame)\" returned true."); } } } /* * resume the target listening for events */ listenUntilVMDisconnect(); /* * deal with results of test * if anything has called failure("foo") testFailed will be true */ if (!testFailed) { println("GetLocalVariables2Test: passed"); } else { throw new Exception("GetLocalVariables2Test: failed"); } }
private void commandLocals() throws NoSessionException { ThreadReference current = context.getCurrentThread(); if (current == null) { env.failure("No default thread specified: " + "use the \"thread\" command first."); return; } StackFrame frame; try { frame = context.getCurrentFrame(current); if (frame == null) { env.failure("Thread has not yet created any stack frames."); return; } } catch (VMNotInterruptedException e) { env.failure("Target VM must be in interrupted state."); return; } List<LocalVariable> vars; try { vars = frame.visibleVariables(); if (vars == null || vars.size() == 0) { env.failure("No local variables"); return; } } catch (AbsentInformationException e) { env.failure( "Local variable information not available." + " Compile with -g to generate variable information"); return; } OutputSink out = env.getOutputSink(); out.println("Method arguments:"); for (LocalVariable var : vars) { if (var.isArgument()) { printVar(out, var, frame); } } out.println("Local variables:"); for (LocalVariable var : vars) { if (!var.isArgument()) { printVar(out, var, frame); } } out.show(); return; }
public char[][] localVariableTypeNames() { try { StackFrame frame = getStackFrame(); Iterator variables = frame.visibleVariables().iterator(); Vector names = new Vector(); while (variables.hasNext()) { LocalVariable var = (LocalVariable) variables.next(); names.addElement(var.typeName().toCharArray()); } char[][] result = new char[names.size()][]; names.copyInto(result); return result; } catch (AbsentInformationException e) { return null; } }
public int[] localVariableModifiers() { try { StackFrame frame = getStackFrame(); List variables = frame.visibleVariables(); int[] modifiers = new int[variables.size()]; /* Iterator iterator = variables.iterator(); int i = 0; while (iterator.hasNext()) { LocalVariable var = (LocalVariable)iterator.next(); // TBD modifiers[i++] = var. ??? ; } */ return modifiers; } catch (AbsentInformationException e) { return null; } }
@Override public Map<IWatchable, IValue> getWatchableValues() { try { StackFrame stackFrame = getStackFrame(); Map<IWatchable, IValue> result = new HashMap<IWatchable, IValue>(); if (stackFrame != null) { Map<LocalVariable, Value> map = stackFrame.getValues(stackFrame.visibleVariables()); for (LocalVariable variable : map.keySet()) { result.put( new JavaLocalVariable(variable, this, myClassFqName, stackFrame.thread()), JavaValue.fromJDIValue(map.get(variable), myClassFqName, stackFrame.thread())); } ObjectReference thisObject = stackFrame.thisObject(); if (thisObject != null) { JavaThisObject object = new JavaThisObject(thisObject, this, myClassFqName, stackFrame.thread()); result.put(object, object.getValue()); } } return result; } catch (AbsentInformationException ex) { // doing nothing return Collections.emptyMap(); } }
private void printVar(OutputSink out, LocalVariable var, StackFrame frame) { out.print(" " + var.name()); if (var.isVisible(frame)) { Value val = frame.getValue(var); out.println(" = " + val.toString()); } else { out.println(" is not in scope"); } }
public boolean isVisible(StackFrame frame) { validateMirror(frame); Method frameMethod = frame.location().method(); if (!frameMethod.equals(method)) { throw new IllegalArgumentException("frame method different than variable's method"); } // this is here to cover the possibility that we will // allow LocalVariables for native methods. If we do // so we will have to re-examinine this. if (frameMethod.isNative()) { return false; } return ((scopeStart.compareTo(frame.location()) <= 0) && (scopeEnd.compareTo(frame.location()) >= 0)); }
public StringReference getLocalVariableValueAsString(StackFrame fr, String localName) throws AbsentInformationException, IncompatibleThreadStateException { Value val = null; StringReference ret = null; LocalVariable var = fr.visibleVariableByName(localName); if (var != null) { val = fr.getValue(var); if (val instanceof StringReference) { ret = (StringReference) fr.getValue(var); } else { LOGGER.warn( "getLocalVariableValueAsString called with non-String Object: " + var.getClass().getName()); } } else { LOGGER.warn("LocalVariable with name: " + localName + " was not found"); } return ret; }
/* * This function appears to take an exorbitant amount of time why why why */ public boolean setLocalVariableValue(int i, String name, Value sf) throws IncompatibleThreadStateException, InvalidTypeException, ClassNotLoadedException, AbsentInformationException { StackFrame frame = this.currentThread.frames().get(i); LocalVariable var = frame.visibleVariableByName(name); LOGGER.info("got var: " + var.typeName()); try { frame.setValue(var, sf); LOGGER.info("success setting new variable value"); return true; } catch (java.lang.ClassCastException e) { /* * KNOWN ISSUE: when checking type compatibility the debugger * requests the ClassLoader of the type of the variable. When an * object is loaded via reflection (using the current method) this * will return an ObjectReference. The debugger is expecting a * ClassLoaderReference and apparently the ObjectReference cannot be * cast to a ClassLoaderReference. */ LOGGER.info( "ClassCastException due to type assignments with classes loaded via reflection, work around is to load class again"); } return false; }
@Override public JavaLocation getLocation() { StackFrame stackFrame = getStackFrame(); if (stackFrame == null) return null; return new JavaLocation(stackFrame.location()); }
private static List<ThreadState> buildThreadStates(VirtualMachineProxyImpl vmProxy) { final List<ThreadReference> threads = vmProxy.getVirtualMachine().allThreads(); final List<ThreadState> result = new ArrayList<ThreadState>(); final Map<String, ThreadState> nameToThreadMap = new HashMap<String, ThreadState>(); final Map<String, String> waitingMap = new HashMap<String, String>(); // key 'waits_for' value for (ThreadReference threadReference : threads) { final StringBuilder buffer = new StringBuilder(); boolean hasEmptyStack = true; final String threadName = threadName(threadReference); final int threadStatus = threadReference.status(); final ThreadState threadState = new ThreadState(threadName, threadStatusToState(threadStatus)); nameToThreadMap.put(threadName, threadState); result.add(threadState); threadState.setJavaThreadState(threadStatusToJavaThreadState(threadStatus)); buffer.append(threadName); ReferenceType referenceType = threadReference.referenceType(); if (referenceType != null) { //noinspection HardCodedStringLiteral Field daemon = referenceType.fieldByName("daemon"); if (daemon != null) { Value value = threadReference.getValue(daemon); if (value instanceof BooleanValue && ((BooleanValue) value).booleanValue()) { buffer .append(" ") .append(DebuggerBundle.message("threads.export.attribute.label.daemon")); } } //noinspection HardCodedStringLiteral Field priority = referenceType.fieldByName("priority"); if (priority != null) { Value value = threadReference.getValue(priority); if (value instanceof IntegerValue) { buffer .append(", ") .append( DebuggerBundle.message( "threads.export.attribute.label.priority", ((IntegerValue) value).intValue())); } } } ThreadGroupReference groupReference = threadReference.threadGroup(); if (groupReference != null) { buffer .append(", ") .append( DebuggerBundle.message( "threads.export.attribute.label.group", groupReference.name())); } buffer .append(", ") .append( DebuggerBundle.message( "threads.export.attribute.label.status", threadState.getState())); buffer.append("\n java.lang.Thread.State: ").append(threadState.getJavaThreadState()); try { if (vmProxy.canGetOwnedMonitorInfo() && vmProxy.canGetMonitorInfo()) { List<ObjectReference> list = threadReference.ownedMonitors(); for (ObjectReference reference : list) { final List<ThreadReference> waiting = reference.waitingThreads(); for (ThreadReference thread : waiting) { final String waitingThreadName = threadName(thread); waitingMap.put(waitingThreadName, threadName); buffer .append("\n\t ") .append( DebuggerBundle.message( "threads.export.attribute.label.blocks.thread", waitingThreadName)); } } } ObjectReference waitedMonitor = vmProxy.canGetCurrentContendedMonitor() ? threadReference.currentContendedMonitor() : null; if (waitedMonitor != null) { if (vmProxy.canGetMonitorInfo()) { ThreadReference waitedMonitorOwner = waitedMonitor.owningThread(); if (waitedMonitorOwner != null) { final String monitorOwningThreadName = threadName(waitedMonitorOwner); waitingMap.put(threadName, monitorOwningThreadName); buffer .append("\n\t ") .append( DebuggerBundle.message( "threads.export.attribute.label.waiting.for.thread", monitorOwningThreadName)); } } } final List<StackFrame> frames = threadReference.frames(); hasEmptyStack = frames.size() == 0; for (StackFrame stackFrame : frames) { final Location location = stackFrame.location(); buffer.append("\n\t ").append(renderLocation(location)); } } catch (IncompatibleThreadStateException e) { buffer .append("\n\t ") .append(DebuggerBundle.message("threads.export.attribute.error.incompatible.state")); } threadState.setStackTrace(buffer.toString(), hasEmptyStack); ThreadDumpParser.inferThreadStateDetail(threadState); } for (String waiting : waitingMap.keySet()) { final ThreadState waitingThread = nameToThreadMap.get(waiting); final ThreadState awaitedThread = nameToThreadMap.get(waitingMap.get(waiting)); awaitedThread.addWaitingThread(waitingThread); } // detect simple deadlocks for (ThreadState thread : result) { for (ThreadState awaitingThread : thread.getAwaitingThreads()) { if (awaitingThread.isAwaitedBy(thread)) { thread.addDeadlockedThread(awaitingThread); awaitingThread.addDeadlockedThread(thread); } } } ThreadDumpParser.sortThreads(result); return result; }
/** * 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; }
private static List<ThreadState> buildThreadStates(VirtualMachineProxyImpl vmProxy) { final List<ThreadReference> threads = vmProxy.getVirtualMachine().allThreads(); final List<ThreadState> result = new ArrayList<ThreadState>(); final Map<String, ThreadState> nameToThreadMap = new HashMap<String, ThreadState>(); final Map<String, String> waitingMap = new HashMap<String, String>(); // key 'waits_for' value for (ThreadReference threadReference : threads) { final StringBuilder buffer = new StringBuilder(); boolean hasEmptyStack = true; final int threadStatus = threadReference.status(); if (threadStatus == ThreadReference.THREAD_STATUS_ZOMBIE) { continue; } final String threadName = threadName(threadReference); final ThreadState threadState = new ThreadState(threadName, threadStatusToState(threadStatus)); nameToThreadMap.put(threadName, threadState); result.add(threadState); threadState.setJavaThreadState(threadStatusToJavaThreadState(threadStatus)); buffer.append("\"").append(threadName).append("\""); ReferenceType referenceType = threadReference.referenceType(); if (referenceType != null) { //noinspection HardCodedStringLiteral Field daemon = referenceType.fieldByName("daemon"); if (daemon != null) { Value value = threadReference.getValue(daemon); if (value instanceof BooleanValue && ((BooleanValue) value).booleanValue()) { buffer .append(" ") .append(DebuggerBundle.message("threads.export.attribute.label.daemon")); threadState.setDaemon(true); } } //noinspection HardCodedStringLiteral Field priority = referenceType.fieldByName("priority"); if (priority != null) { Value value = threadReference.getValue(priority); if (value instanceof IntegerValue) { buffer .append(" ") .append( DebuggerBundle.message( "threads.export.attribute.label.priority", ((IntegerValue) value).intValue())); } } Field tid = referenceType.fieldByName("tid"); if (tid != null) { Value value = threadReference.getValue(tid); if (value instanceof LongValue) { buffer .append(" ") .append( DebuggerBundle.message( "threads.export.attribute.label.tid", Long.toHexString(((LongValue) value).longValue()))); buffer.append(" nid=NA"); } } } // ThreadGroupReference groupReference = threadReference.threadGroup(); // if (groupReference != null) { // buffer.append(", ").append(DebuggerBundle.message("threads.export.attribute.label.group", // groupReference.name())); // } final String state = threadState.getState(); if (state != null) { buffer.append(" ").append(state); } buffer.append("\n java.lang.Thread.State: ").append(threadState.getJavaThreadState()); try { if (vmProxy.canGetOwnedMonitorInfo() && vmProxy.canGetMonitorInfo()) { List<ObjectReference> list = threadReference.ownedMonitors(); for (ObjectReference reference : list) { if (!vmProxy.canGetMonitorFrameInfo()) { // java 5 and earlier buffer.append("\n\t ").append(renderLockedObject(reference)); } final List<ThreadReference> waiting = reference.waitingThreads(); for (ThreadReference thread : waiting) { final String waitingThreadName = threadName(thread); waitingMap.put(waitingThreadName, threadName); buffer .append("\n\t ") .append( DebuggerBundle.message( "threads.export.attribute.label.blocks.thread", waitingThreadName)); } } } ObjectReference waitedMonitor = vmProxy.canGetCurrentContendedMonitor() ? threadReference.currentContendedMonitor() : null; if (waitedMonitor != null) { if (vmProxy.canGetMonitorInfo()) { ThreadReference waitedMonitorOwner = waitedMonitor.owningThread(); if (waitedMonitorOwner != null) { final String monitorOwningThreadName = threadName(waitedMonitorOwner); waitingMap.put(threadName, monitorOwningThreadName); buffer .append("\n\t ") .append( DebuggerBundle.message( "threads.export.attribute.label.waiting.for.thread", monitorOwningThreadName, renderObject(waitedMonitor))); } } } final List<StackFrame> frames = threadReference.frames(); hasEmptyStack = frames.size() == 0; final TIntObjectHashMap<List<ObjectReference>> lockedAt = new TIntObjectHashMap<List<ObjectReference>>(); if (vmProxy.canGetMonitorFrameInfo()) { for (MonitorInfo info : threadReference.ownedMonitorsAndFrames()) { final int stackDepth = info.stackDepth(); List<ObjectReference> monitors; if ((monitors = lockedAt.get(stackDepth)) == null) { lockedAt.put(stackDepth, monitors = new SmartList<ObjectReference>()); } monitors.add(info.monitor()); } } for (int i = 0, framesSize = frames.size(); i < framesSize; i++) { final StackFrame stackFrame = frames.get(i); try { final Location location = stackFrame.location(); buffer.append("\n\t ").append(renderLocation(location)); final List<ObjectReference> monitors = lockedAt.get(i); if (monitors != null) { for (ObjectReference monitor : monitors) { buffer.append("\n\t - ").append(renderLockedObject(monitor)); } } } catch (InvalidStackFrameException e) { buffer.append("\n\t Invalid stack frame: ").append(e.getMessage()); } } } catch (IncompatibleThreadStateException e) { buffer .append("\n\t ") .append(DebuggerBundle.message("threads.export.attribute.error.incompatible.state")); } threadState.setStackTrace(buffer.toString(), hasEmptyStack); ThreadDumpParser.inferThreadStateDetail(threadState); } for (String waiting : waitingMap.keySet()) { final ThreadState waitingThread = nameToThreadMap.get(waiting); final ThreadState awaitedThread = nameToThreadMap.get(waitingMap.get(waiting)); awaitedThread.addWaitingThread(waitingThread); } // detect simple deadlocks for (ThreadState thread : result) { for (ThreadState awaitingThread : thread.getAwaitingThreads()) { if (awaitingThread.isAwaitedBy(thread)) { thread.addDeadlockedThread(awaitingThread); awaitingThread.addDeadlockedThread(thread); } } } ThreadDumpParser.sortThreads(result); return result; }
private static void renderTrace(List<StackFrame> frames, StringBuilder buffer) { for (final StackFrame stackFrame : frames) { final Location location = stackFrame.location(); buffer.append("\n\t ").append(ThreadDumpAction.renderLocation(location)); } }
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; }
private void commandList(StringTokenizer t) throws NoSessionException { ThreadReference current = context.getCurrentThread(); if (current == null) { env.error("No thread specified."); return; } Location loc; try { StackFrame frame = context.getCurrentFrame(current); if (frame == null) { env.failure("Thread has not yet begun execution."); return; } loc = frame.location(); } catch (VMNotInterruptedException e) { env.failure("Target VM must be in interrupted state."); return; } SourceModel source = sourceManager.sourceForLocation(loc); if (source == null) { if (loc.method().isNative()) { env.failure("Current method is native."); return; } env.failure("No source available for " + Utils.locationString(loc) + "."); return; } ReferenceType refType = loc.declaringType(); int lineno = loc.lineNumber(); if (t.hasMoreTokens()) { String id = t.nextToken(); // See if token is a line number. try { lineno = Integer.valueOf(id).intValue(); } catch (NumberFormatException nfe) { // It isn't -- see if it's a method name. List<Method> meths = refType.methodsByName(id); if (meths == null || meths.size() == 0) { env.failure( id + " is not a valid line number or " + "method name for class " + refType.name()); return; } else if (meths.size() > 1) { env.failure(id + " is an ambiguous method name in" + refType.name()); return; } loc = meths.get(0).location(); lineno = loc.lineNumber(); } } int startLine = (lineno > 4) ? lineno - 4 : 1; int endLine = startLine + 9; String sourceLine = source.sourceLine(lineno); if (sourceLine == null) { env.failure("" + lineno + " is an invalid line number for " + refType.name()); } else { OutputSink out = env.getOutputSink(); for (int i = startLine; i <= endLine; i++) { sourceLine = source.sourceLine(i); if (sourceLine == null) { break; } out.print(i); out.print("\t"); if (i == lineno) { out.print("=> "); } else { out.print(" "); } out.println(sourceLine); } out.show(); } }
@Override public JavaThread getThread() { StackFrame stackFrame = getStackFrame(); if (stackFrame == null) return null; return new JavaThread(stackFrame.thread()); }