/** * @since 0.17 */ @Override public String toString() { return "Suspended at " + getSourceSection() + " for thread " + getThread(); }
/** * Returns the return value of the currently executed source location. Returns <code>null</code> * if the execution is suspended {@link SuspendAnchor#BEFORE before} a guest language location. * The returned value is <code>null</code> if an exception occurred during execution of the * instrumented source element, the exception is provided by {@link #getException()}. * <p> * This method is not thread-safe and will throw an {@link IllegalStateException} if called on * another thread than it was created with. * * @since 0.17 */ public DebugValue getReturnValue() { verifyValidState(false); Object ret = returnValue; if (ret == null) { return null; } return getTopStackFrame().wrapHeapValue(ret); }
private SuspendedContext getContext() { SuspendedContext context = event.getContext(); if (context == null) { // there is a race condition here if the event // got disposed between the parent verifyValidState and getContext. // if the context is null we assume the event got disposed so we re-check // the disposed flag. return null should therefore not be reachable. verifyValidState(true); assert false : "should not be reachable"; } return context; }
lineResolved, event.getSourceSection().getStartLine()); Assert.assertSame(breakpoint, event.getBreakpoints().iterator().next()); event.prepareContinue(); }); expectDone();
Object newReturnValue; try { suspendedEvent = new SuspendedEvent(this, currentThread, context, frame, suspendAnchor, insertableNode, inputValuesProvider, returnValue, exception, breaks, conditionFailures); if (exception != null) { exception.setSuspendedEvent(suspendedEvent); } finally { currentSuspendedEventMap.remove(currentThread); newReturnValue = suspendedEvent.getReturnObject(); suspendedEvent.clearLeakingReferences(); SteppingStrategy strategy = suspendedEvent.getNextStrategy(); if (!strategy.isKill()) {
MaterializedFrame frame; if (frameInstance == null) { node = ev.getContext().getInstrumentedNode(); frame = ev.getMaterializedFrame(); } else { node = frameInstance.getCallNode(); return evalInContext(ev, node, frame, code); } catch (KillException kex) { throw new DebugException(ev.getSession(), "Evaluation was killed.", null, true, null); } catch (Throwable ex) { LanguageInfo language = null; language = root.getLanguageInfo(); throw new DebugException(ev.getSession(), ex, language, null, true, null);
suspendedEvent = new SuspendedEvent(this, currentThread, context, frame, suspendAnchor, inputValuesProvider, returnValue, breaks, conditionFailures); currentSuspendedEventMap.put(currentThread, suspendedEvent); try { suspendedEvent.clearLeakingReferences(); SteppingStrategy strategy = suspendedEvent.getNextStrategy(); if (!strategy.isKill()) {
void setSuspendedEvent(SuspendedEvent suspendedEvent) { assert session == suspendedEvent.getSession(); if (catchLocation != null) { catchLocation.setSuspendedEvent(suspendedEvent); } this.suspendedEvent = suspendedEvent; }
private void assertBreakpoints(Source source, List<Breakpoint> breakpoints, Set<Breakpoint> breakpointsResolved, List<Breakpoint> breakpointsHit) { try (DebuggerSession session = startSession()) { for (Breakpoint breakpoint : breakpoints) { session.install(breakpoint); } startEval(source); while (breakpointsHit.size() != breakpoints.size()) { expectSuspended((SuspendedEvent event) -> { breakpointsHit.addAll(event.getBreakpoints()); event.prepareContinue(); }); } expectDone(); } Assert.assertEquals(breakpoints.size(), breakpointsResolved.size()); Assert.assertEquals(breakpoints.size(), breakpointsHit.size()); }
/** * Evaluates a snippet of code in a halted execution context. Assumes frame is part of the * current execution stack, behavior is undefined if not. * * @param ev event notification where execution is halted * @param code text of the code to be executed * @param frameInstance frame where execution is halted * @return * @throws IOException */ static Object evalInContext(SuspendedEvent ev, String code, FrameInstance frameInstance) throws IOException { try { Node node; MaterializedFrame frame; if (frameInstance == null) { node = ev.getContext().getInstrumentedNode(); frame = ev.getMaterializedFrame(); } else { node = frameInstance.getCallNode(); frame = frameInstance.getFrame(FrameAccess.MATERIALIZE).materialize(); } return Debugger.ACCESSOR.evalInContext(node, frame, code); } catch (KillException kex) { throw new IOException("Evaluation was killed.", kex); } }
public void onSuspend(SuspendedEvent ev) { actualName[0] = ev.getTopStackFrame().getName(); haltCount[0] = haltCount[0] + 1; } })) {
private static Object evalInContext(SuspendedEvent ev, Node node, MaterializedFrame frame, String code) { RootNode rootNode = node.getRootNode(); if (rootNode == null) { throw new IllegalArgumentException("Cannot evaluate in context using a node that is not yet adopated using a RootNode."); } LanguageInfo info = rootNode.getLanguageInfo(); if (info == null) { throw new IllegalArgumentException("Cannot evaluate in context using a without an associated TruffleLanguage."); } if (!info.isInteractive()) { throw new IllegalStateException("Can not evaluate in a non-interactive language."); } final Source source = Source.newBuilder(info.getId(), code, "eval in context").build(); ExecutableNode fragment = ev.getSession().getDebugger().getEnv().parseInline(source, node, frame); if (fragment != null) { ev.getInsertableNode().setParentOf(fragment); return fragment.execute(frame); } else { return Debugger.ACCESSOR.evalInContext(source, node, frame); } }
MaterializedFrame findTruffleFrame() { if (currentFrame == null) { return event.getMaterializedFrame(); } else { return currentFrame.getFrame(FrameAccess.MATERIALIZE).materialize(); } }
/** * Returns the topmost stack frame returned by {@link #getStackFrames()}. * <p> * This method is not thread-safe and will throw an {@link IllegalStateException} if called on * another thread than it was created with. * * @see #getStackFrames() * @since 0.17 */ public DebugStackFrame getTopStackFrame() { // there must be always a top stack frame. return getStackFrames().iterator().next(); }
bp[1], event.getSourceSection().getCharIndex() + 1); Assert.assertSame(breakpoint, event.getBreakpoints().iterator().next()); event.prepareContinue(); }); expectDone();
private CatchLocation cloneFor(DebuggerSession ds) { assert this.session == null; CatchLocation clon = new CatchLocation(ds, section, frameInstance, depth); if (frame != null) { assert ds == frame.event.getSession(); clon.frame = frame; } return clon; } }
private void assertBreakpoints(Source source, List<Breakpoint> breakpoints, Set<Breakpoint> breakpointsResolved, List<Breakpoint> breakpointsHit) { try (DebuggerSession session = startSession(new SourceElement[0])) { for (Breakpoint breakpoint : breakpoints) { session.install(breakpoint); } startEval(source); while (breakpointsHit.size() != breakpoints.size()) { try { expectSuspended((SuspendedEvent event) -> { breakpointsHit.addAll(event.getBreakpoints()); event.prepareContinue(); }); } catch (Throwable t) { Set<Breakpoint> notHit = new HashSet<>(breakpoints); notHit.removeAll(breakpointsHit); for (Breakpoint b : notHit) { err("Not hit " + b + ": " + b.getLocationDescription()); } err("---"); for (Breakpoint b : breakpointsHit) { err("Hit " + b + ": " + b.getLocationDescription()); } throw t; } } expectDone(); } Assert.assertEquals(breakpoints.size(), breakpointsResolved.size()); Assert.assertEquals(breakpoints.size(), breakpointsHit.size()); }
/** * Returns the input values of the current source element gathered from return values of it's * executed children. The input values are available only during stepping through the source * elements hierarchy and only on {@link SuspendAnchor#AFTER AFTER} {@link #getSuspendAnchor() * suspend anchor}. There can be <code>null</code> values in the returned array for children we * did not intercept return values from. * * @return the array of input values, or <code>null</code> when no input is available. * @since 0.33 */ public DebugValue[] getInputValues() { if (inputValuesProvider == null) { return null; } Object[] inputValues = inputValuesProvider.getDebugInputValues(materializedFrame); int n = inputValues.length; DebugValue[] values = new DebugValue[n]; for (int i = 0; i < n; i++) { if (inputValues[i] != null) { values[i] = getTopStackFrame().wrapHeapValue(inputValues[i]); } else { values[i] = null; } } return values; }
MaterializedFrame findTruffleFrame() { if (currentFrame == null) { return event.getMaterializedFrame(); } else { return currentFrame.getFrame(FrameAccess.MATERIALIZE).materialize(); } }
/** * Returns the topmost stack frame returned by {@link #getStackFrames()}. * <p> * This method is not thread-safe and will throw an {@link IllegalStateException} if called on * another thread than it was created with. * * @see #getStackFrames() * @since 0.17 */ public DebugStackFrame getTopStackFrame() { // there must be always a top stack frame. return getStackFrames().iterator().next(); }