boolean handleNewArray(final ArrayReference array, final Location location, final StackFrame frame) { if (array == null || !manager().generateArrayEvents()) { return false; } // handle the instantiation of of small arrays if (array != null && array.length() <= EventFactoryAdapter.SMALL_ARRAY_SIZE && contourFactory().lookupInstanceContour(array.type().name(), array.uniqueID()) == null) { handleTypeLoad((ReferenceType) array.type(), frame.thread()); // a specialized new event handles the immutable length of the array manager().jiveDispatcher().dispatchNewEvent(array, frame.thread(), array.length()); visitArrayCells(location, frame, array); return true; } return false; }
public void popFrames (ThreadReference thread, StackFrame frame) { PropertyChangeEvent evt = null; accessLock.readLock().lock(); try { JPDAThreadImpl threadImpl = getThread(thread); setState (STATE_RUNNING); try { threadImpl.popFrames(frame); evt = updateCurrentCallStackFrameNoFire(threadImpl); } catch (IncompatibleThreadStateException ex) { Exceptions.printStackTrace(ex); } finally { setState (STATE_STOPPED); } } finally { accessLock.readLock().unlock(); } if (evt != null) { firePropertyChange(evt); } }
/** * Creates a new context in which to evaluate expressions. * * @param frame the frame in which context evaluation occurs * @param imports list of imports * @param staticImports list of static imports */ public EvaluationContext(JPDAThreadImpl thread, StackFrame frame, int frameDepth, ObjectReference contextVariable, List<String> imports, List<String> staticImports, boolean canInvokeMethods, Runnable methodInvokePreproc, JPDADebuggerImpl debugger, VMCache vmCache) { if (thread == null) throw new IllegalArgumentException("Thread argument must not be null"); if (frame == null) throw new IllegalArgumentException("Frame argument must not be null"); if (imports == null) throw new IllegalArgumentException("Imports argument must not be null"); if (staticImports == null) throw new IllegalArgumentException("Static imports argument must not be null"); this.thread = thread; this.frame = frame; this.frameDepth = frameDepth; this.contextVariable = contextVariable; this.sourceImports = imports; this.staticImports = staticImports; this.canInvokeMethods = canInvokeMethods; this.methodInvokePreproc = methodInvokePreproc; this.debugger = debugger; this.vmCache = vmCache; stack.push(new HashMap<String, ScriptVariable>()); }
private String getCurrentClassName() { JPDADebuggerImpl debugger = (JPDADebuggerImpl) support.getDebugger(); String className = null; try { JPDAThreadImpl jpdaThread = (JPDAThreadImpl) debugger.getCurrentThread(); if (jpdaThread == null) { System.err.println("NULL Current Thread!"); Thread.dumpStack(); } else { StackFrame sf = jpdaThread.getThreadReference().frame(0); if (sf == null) { System.err.println("No stack frame!"); Thread.dumpStack(); } else { className = sf.location().declaringType().name(); } } } catch (Exception e) { e.printStackTrace(); } return className; }
/********** test core **********/ protected void runTests() throws Exception { /* * Run to String.<init> */ startUp("GetUninitializedStringValueTarg"); BreakpointEvent bpe = resumeTo("java.lang.String", "<init>", "(Ljava/lang/String;)V"); /* * We've arrived. Look at 'this' - it will be uninitialized (the value field will not be set yet). */ StackFrame frame = bpe.thread().frame(0); StringReference sr = (StringReference)frame.thisObject(); if (!sr.value().equals("")) { throw new Exception("Unexpected value for the uninitialized String"); } /* * resume the target listening for events */ listenUntilVMDisconnect(); }
public static int getLockRecursions(VirtualMachine vm) { List <ThreadReference> threads = vm.allThreads(); for (ThreadReference thread : threads) { if (thread.name().equals("main")) { System.out.println("Found main thread."); try{ StackFrame frame = thread.frame(3); return frame.thisObject().entryCount(); } catch (Exception e) { e.printStackTrace(); } } System.out.println("Main thread not found!"); } return -1; }
public boolean isAtBreakpoint() { /* * TO DO: This fails to take filters into account. */ try { StackFrame frame = frame(0); Location location = frame.location(); List<BreakpointRequest> requests = vm.eventRequestManager().breakpointRequests(); Iterator<BreakpointRequest> iter = requests.iterator(); while (iter.hasNext()) { BreakpointRequest request = iter.next(); if (location.equals(request.location())) { return true; } } return false; } catch (IndexOutOfBoundsException iobe) { return false; // no frames on stack => not at breakpoint } catch (IncompatibleThreadStateException itse) { // Per the javadoc, not suspended => return false return false; } }
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)); }
private Types.StackFrame convertDebuggerStackFrameToClient(StackFrame stackFrame, int frameId, IDebugAdapterContext context) throws URISyntaxException, AbsentInformationException { Location location = stackFrame.location(); Method method = location.method(); Types.Source clientSource = this.convertDebuggerSourceToClient(location, context); String methodName = formatMethodName(method, true, true); int lineNumber = AdapterUtils.convertLineNumber(location.lineNumber(), context.isDebuggerLinesStartAt1(), context.isClientLinesStartAt1()); // Line number returns -1 if the information is not available; specifically, always returns -1 for native methods. if (lineNumber < 0) { if (method.isNative()) { // For native method, display a tip text "native method" in the Call Stack View. methodName += "[native method]"; } else { // For other unavailable method, such as lambda expression's built-in methods run/accept/apply, // display "Unknown Source" in the Call Stack View. clientSource = null; } } return new Types.StackFrame(frameId, methodName, clientSource, lineNumber, 0); }
/** * Given a stack frame, find the target project that the associated source file belongs to. * * @param stackFrame * the stack frame. * @param containers * the source container list. * @return the context project. */ public static IProject findProject(StackFrame stackFrame, ISourceContainer[] containers) { Location location = stackFrame.location(); try { Object sourceElement = findSourceElement(location.sourcePath(), containers); if (sourceElement instanceof IResource) { return ((IResource) sourceElement).getProject(); } else if (sourceElement instanceof IClassFile) { IJavaProject javaProject = ((IClassFile) sourceElement).getJavaProject(); if (javaProject != null) { return javaProject.getProject(); } } } catch (AbsentInformationException e) { // When the compiled .class file doesn't contain debug source information, return null. } return null; }
/** * Returns a list of frames which should be popped in the given threads. */ private List<StackFrame> getAffectedFrames(List<ThreadReference> threads, List<String> replacedClassNames) throws DebugException { List<StackFrame> popFrames = new ArrayList<>(); for (ThreadReference thread : threads) { if (thread.isSuspended()) { StackFrame affectedFrame = getAffectedFrame(thread, replacedClassNames); if (affectedFrame == null) { // No frame to drop to in this thread continue; } if (supportsDropToFrame(thread, affectedFrame)) { popFrames.add(affectedFrame); } } } return popFrames; }
private boolean containsChangedType(StackFrame frame, List<String> replacedClassNames) throws DebugException { String declaringTypeName = getDeclaringTypeName(frame); // Check if the frame's declaring type was changed if (replacedClassNames.contains(declaringTypeName)) { return true; } // Check if one of the frame's declaring type's inner classes have // changed for (String className : replacedClassNames) { int index = className.indexOf('$'); if (index > -1 && declaringTypeName.equals(className.substring(0, index))) { return true; } } return false; }
private boolean containsObsoleteMethods() throws DebugException { List<ThreadReference> threads = currentDebugSession.getAllThreads(); for (ThreadReference thread : threads) { if (!thread.isSuspended()) { continue; } List<StackFrame> frames = getStackFrames(thread, false); if (frames == null || frames.isEmpty()) { continue; } for (StackFrame frame : frames) { if (StackFrameUtility.isObsolete(frame)) { return true; } } } return false; }
private List<StackFrame> getFilteredFrames() throws IncompatibleThreadStateException { List<StackFrame> frames = F3Wrapper.wrapFrames(virtualMachine(), underlying().frames()); List<StackFrame> filteredFrames = new ArrayList<StackFrame>(frames.size()); try { for (StackFrame fr : frames) { F3StackFrame f3fr = (F3StackFrame) fr; // don't add F3 synthetic frames if (f3fr.location().method().isF3InternalMethod()) { continue; } else { filteredFrames.add(f3fr); } } } catch (InvalidStackFrameException exp) { throw new IncompatibleThreadStateException(exp.getMessage()); } return filteredFrames; }
/** * Evaluate "jdb"-style expressions. The expression syntax is same as what * you'd use with jdb's "print" or "set" command. The expression is evaluated * in current thread's current frame context. You can access locals from that * frame and also evaluate object fields/static fields etc. from there. For * example, if "seq" is a local variable of type F3 integer sequence, * * Debugger dbg = ... * dbg.evaluate("seq[0]"); * * and that will return JDI IntegerValue type object in this case. */ public Value evaluate(String expr) { Value result = null; ExpressionParser.GetFrame frameGetter = null; try { final ThreadInfo threadInfo = env.getCurrentThreadInfo(); if (threadInfo != null && threadInfo.getCurrentFrame() != null) { frameGetter = new ExpressionParser.GetFrame() { public StackFrame get() throws IncompatibleThreadStateException { return threadInfo.getCurrentFrame(); } }; } result = ExpressionParser.evaluate(expr, env.vm(), frameGetter); } catch (RuntimeException rexp) { throw rexp; } catch (Exception exp) { throw new RuntimeException(exp); } return result; }
void nameTest(int start, int length) { try { List fs = mainThread.frames(start, length); if (fs.size() != length) { failure("wrong length for: " + "start = " + start + ", length = " + length); } for (int i = 0; i < length; ++i) { StackFrame sf = (StackFrame)(fs.get(i)); String name = sf.location().method().name(); String expected = expectedNames[start+i]; if (!name.equals(expected)) { failure("bad frame entry (" + start + "," + length + ") - expected " + expected + ", got " + name); } } } catch (Exception exc) { failure("unexpected exception thrown for: " + "start = " + start + ", length = " + length + " - " + exc); } }
/********** test core **********/ protected void runTests() throws Exception { /* * Get to the top of main() * to determine targetClass and mainThread */ BreakpointEvent bpe = startToMain(targetClassName); targetClass = bpe.location().declaringType(); mainThread = bpe.thread(); int initialSize = mainThread.frames().size(); resumeTo(targetClassName, "foo3", "()V"); if (!mainThread.frame(0).location().method().name() .equals("foo3")) { failure("frame failed"); } // not F3 frames for (StackFrame fr : mainThread.frames()) { Assert.assertEquals(false, ((F3StackFrame)fr).isF3Frame()); } if (mainThread.frames().size() != (initialSize + 3)) { failure("frames size failed"); } if (mainThread.frames().size() != mainThread.frameCount()) { failure("frames size not equal to frameCount"); } exceptionTest(-1, 1); exceptionTest(mainThread.frameCount(), 1); exceptionTest(0, -1); exceptionTest(0, -2); exceptionTest(0, mainThread.frameCount()+1); nameTest(0, 0); nameTest(0, 1); nameTest(0, 4); nameTest(2, 2); nameTest(1, 1); /* * resume until end */ listenUntilVMDisconnect(); /* * deal with results of test * if anything has called failure("foo") testFailed will be true */ if (!testFailed) { println("FramesTest: passed"); } else { throw new Exception("FramesTest: failed"); } }
@Test(timeout=5000) public void testHello1() { try { compile("LocalVar.f3"); stop("in LocalVar.f3$run$"); f3run(); BreakpointEvent bkpt = resumeToBreakpoint(); // We hide F3 synthetic variables. F3StackFrame frame = (F3StackFrame) bkpt.thread().frame(0); LocalVariable var = frame.visibleVariableByName("_$UNUSED$_$ARGS$_"); Assert.assertNull(var); // underlying (java) frame object exposes this variable. StackFrame jframe = F3Wrapper.unwrap(frame); var = jframe.visibleVariableByName("_$UNUSED$_$ARGS$_"); Assert.assertNotNull(var); resumeToVMDeath(); quit(); } catch (Exception exp) { exp.printStackTrace(); Assert.fail(exp.getMessage()); } }
IJiveEvent createCatchEvent(final StackFrame catchFrame, final ExceptionEvent event) { final IThreadValue threadId = resolveThread(catchFrame); final StackFrame frame = executionState().framePeek(catchFrame.thread().uniqueID()); if (!executionState().containsInModelFrame(frame)) { throw new IllegalStateException("A method contour was not found for the given stack frame."); } final IMethodContour catcher = executionState().lookupContour(frame); final IValue exception = resolveReference(event.thread(), event.exception(), null); final IContourMember variable = resolveCatchVariable(event, catchFrame, catcher); // update the source location-- no harm done if the location hasn't changed executionState().nextLine(threadId, resolveLine(event.catchLocation())); final ILineValue line = executionState().currentLine(threadId); return eventFactory().createExceptionCatchEvent(threadId, line, exception, variable); }
IJiveEvent createThrowEvent(final ThreadReference thread, final ObjectReference ref) { final IThreadValue threadId = resolveThread(thread); final boolean wasFramePopped = false; final IValue thrower = resolveThrower(thread, false); final IValue exception = resolveReference(thread, ref, null); final StackFrame frame = executionState().framePeek(thread.uniqueID()); // defensively record the location-- no harm done if the location hasn't changed final ILineValue nextLine = resolveLine(frame); if (nextLine != valueFactory().createUnavailableLine()) { executionState().nextLine(threadId, nextLine); } final ILineValue line = executionState().currentLine(threadId); return eventFactory().createExceptionThrowEvent(threadId, line, exception, thrower, wasFramePopped); }
@Override public IContextContour retrieveContext(final StackFrame frame) { final StackFrame f = toJiveStackFrame(frame); final Method method = f.location().method(); final ReferenceType type = method.declaringType(); if (method.isStatic() || method.isNative()) { return contourFactory().retrieveStaticContour(type.name()); } else { final ObjectReference object = f.thisObject(); return contourFactory().retrieveInstanceContour(type.name(), object.uniqueID()); } }
/** * Returns whether the given thread contains any in-model frames (i.e., whether there is a frame * on the stack with a corresponding contour) between the top frame and the frame matching the * supplied location. */ private boolean containsInModelFrames(final ThreadReference thread, final Location catchLocation) throws IncompatibleThreadStateException { final List<StackFrame> stack = thread.frames(); for (final StackFrame frame : stack) { final ReferenceType type = frame.location().declaringType(); if (eventFilter().acceptsType(type)) { return true; } if (catchLocation != null && frame.location().method().equals(catchLocation.method())) { return false; } } return false; }
private boolean visitArrayCells(final Location location, final StackFrame frame, final ArrayReference arrayRef) { // only process small arrays if (!manager().generateArrayEvents() || arrayRef == null || arrayRef.length() > EventFactoryAdapter.SMALL_ARRAY_SIZE) { return false; } // retrieve the array reference type final ArrayType at = (ArrayType) arrayRef.type(); // retrieve the array contour final IContextContour array = contourFactory().lookupInstanceContour(at.name(), arrayRef.uniqueID()); // make sure the respective array contour exists if (array == null) { return false; } return visitArrayCells(location, frame, arrayRef, array); }
/** * Filtered method calls/returns are captured lazily by determineStackFrame(event). */ void handleMethodEntry(final MethodEntryEvent event, final boolean generateLocals) throws IncompatibleThreadStateException, AbsentInformationException { if (!eventFilter().acceptsMethod(event.method(), event.thread())) { return; } // adjust the stack frames if necessary final StackFrame frame = determineStackFrame(event); // handle a pending returned event if necessary handlePendingReturned(event.location(), frame, event.thread()); // record newly observed types and objects if necessary handleNewObject(frame, event.thread()); // resolve the method resolveMethod(frame, event.method()); // record the method call dispatcher().dispatchInModelCallEvent(event, frame); // handle locals if necessary if (generateLocals) { handleLocals(null, frame, event.location()); } }
/** * Instance processing creates all the necessary static and instance schemas, dispatches any * number of type load events followed by at most one new object event, if necessary. */ void handleNewObject(final StackFrame frame, final ThreadReference thread) { final Location location = frame.location(); if (location == null) { return; } final Method method = location.method(); if (method == null) { return; } handleTypeLoad(method.declaringType(), thread); final ObjectReference object = frame.thisObject(); handleNewObject(object, thread); }
/** * Creates a node for this method, if one does not exist. */ IMethodNode resolveMethod(final StackFrame frame, final Method method) { final String methodKey = executionState().methodKey(method); // resolve the declaring class for the method final ITypeNode type = resolveType(method.declaringType()).node(); // lookup the method final IMethodNode result = staticModelFactory().lookupMethodNode(methodKey); // null is returned only for JDI methods if (result != null) { return result; } // the adapter creates static model nodes using AST when possible and JDI otherwise final IStaticModelDelegate adapter = adapterForAST(method.virtualMachine()); // create and return the missing method node return adapter.resolveMethod(type, method, methodKey); }
/** * Contructs a nwe {@link AbstractBreakpointValue} * @param value the value that the watchpoint took at the corresponding timestamp * @param object the instance to which the value belong * @param location the method, source file and line number of the caller * @param timestamp the timestamp at which the watchpoint's variable took the corresponding value * @param thread the thread which set the value */ public AbstractBreakpointValue(int timestamp, ThreadReference thread) { try { @SuppressWarnings("unchecked") List<StackFrame> frames = thread.frames(); int frameSize = frames.size(); sourceNames = new ArrayList<String>(frameSize); methodNames = new ArrayList<String>(frameSize); lineNumbers = new ArrayList<Integer>(frameSize); for (StackFrame frame : frames) { Location location = frame.location(); Method method = location.method(); sourceNames.add(location.sourcePath()); methodNames.add(method.name() + method.signature()); lineNumbers.add(location.lineNumber()); } } catch (Exception e) { } this.timestamp = timestamp; this.threadName = thread.name(); }
private Data processThis(ExceptionEvent event, ReferenceType ref, ThreadReference thread) { StackFrame stack = null; try { stack = thread.frame(0); } catch (IncompatibleThreadStateException e) { e.printStackTrace(); } Data valueThis = utils.getObj("this", stack.thisObject(), new ArrayList<Long>()); return valueThis; }
/** Creates the context, do not call directly */ public Context(Lookup context) { this.callStackFrame = context.lookup(CallStackFrame.class); this.contextVariable = context.lookup(ObjectVariable.class); this.stackFrame = context.lookup(StackFrame.class); this.stackDepth = context.lookup(Integer.class); this.contextObject = context.lookup(ObjectReference.class); this.methodToBeInvokedNotifier = context.lookup(Runnable.class); }
public boolean sendStopUserCode() throws IllegalStateException { if (closed) { return false; } vm.suspend(); try { ObjectReference myRef = getAgentObjectReference(); OUTER: for (ThreadReference thread : vm.allThreads()) { // could also tag the thread (e.g. using name), to find it easier AGENT: for (StackFrame frame : thread.frames()) { if (REMOTE_AGENT_CLASS.equals(frame.location().declaringType().name())) { String n = frame.location().method().name(); if (AGENT_INVOKE_METHOD.equals(n) || AGENT_VARVALUE_METHOD.equals(n)) { ObjectReference thiz = frame.thisObject(); if (myRef != null && myRef != thiz) { break AGENT; } if (((BooleanValue) thiz.getValue(thiz.referenceType().fieldByName("inClientCode"))).value()) { thiz.setValue(thiz.referenceType().fieldByName("expectingStop"), vm.mirrorOf(true)); ObjectReference stopInstance = (ObjectReference) thiz.getValue(thiz.referenceType().fieldByName("stopException")); vm.resume(); thread.stop(stopInstance); thiz.setValue(thiz.referenceType().fieldByName("expectingStop"), vm.mirrorOf(false)); } return true; } } } } } catch (ClassNotLoadedException | IncompatibleThreadStateException | InvalidTypeException ex) { throw new IllegalStateException(ex); } finally { vm.resume(); } return false; }
private int indexOf(List<StackFrame> frames, StackFrame frame) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, InvalidStackFrameExceptionWrapper { int n = frames.size(); Location loc = StackFrameWrapper.location(frame); for (int i = 0; i < n; i++) { if (loc.equals(StackFrameWrapper.location(frames.get(i)))) return i; } return -1; }
/** * Get the current stackframe. * * @return the current stackframe. */ StackFrame getCurrentFrame() throws IncompatibleThreadStateException { if (thread.frameCount() == 0) { return null; } return thread.frame(currentFrameIndex); }