use of com.oracle.truffle.api.debug.DebugStackFrame in project graal by oracle.
the class DebugStackFrameTest method testEvalAndSideEffects.
@Test
public void testEvalAndSideEffects() throws Throwable {
final Source source = testSource("ROOT(DEFINE(a,ROOT( \n" + " VARIABLE(a, 42), \n" + " VARIABLE(b, 43), \n" + " VARIABLE(c, 44), \n" + // will start stepping here
" STATEMENT(),\n" + " STATEMENT())\n" + "), \n" + "VARIABLE(a, 42), VARIABLE(b, 43), VARIABLE(c, 44), \n" + "CALL(a))\n");
try (DebuggerSession session = startSession()) {
session.suspendNextExecution();
startEval(source);
expectSuspended((SuspendedEvent event) -> {
Iterator<DebugStackFrame> stackFrames = event.getStackFrames().iterator();
// assert changes to the current frame
DebugStackFrame frame = stackFrames.next();
assertDynamicFrame(frame);
DebugValue aValue = frame.getScope().getDeclaredValue("a");
String aStringValue = aValue.as(String.class);
// assert changes to a parent frame
frame = stackFrames.next();
assertDynamicFrame(frame);
// assign from one stack frame to another one
frame.getScope().getDeclaredValue("a").set(aValue);
assertEquals(aStringValue, frame.getScope().getDeclaredValue("a").as(String.class));
event.prepareContinue();
});
expectDone();
}
}
use of com.oracle.truffle.api.debug.DebugStackFrame in project graal by oracle.
the class DebugStackFrameTest method testSourceSections.
@Test
public void testSourceSections() {
final Source source = testSource("ROOT(DEFINE(a,ROOT(\n" + " STATEMENT())\n" + "),\n" + "DEFINE(b,ROOT(\n" + " CALL(a))\n" + "), \n" + "CALL(b))\n");
try (DebuggerSession session = startSession()) {
session.suspendNextExecution();
startEval(source);
expectSuspended((SuspendedEvent event) -> {
DebugStackFrame frame = event.getTopStackFrame();
SourceSection ss = frame.getSourceSection();
assertSection(ss, "STATEMENT()", 2, 3, 2, 13);
SourceSection fss = getFunctionSourceSection(frame);
assertSection(fss, "ROOT(\n STATEMENT())\n", 1, 15, 2, 15);
Iterator<DebugStackFrame> stackFrames = event.getStackFrames().iterator();
// The top one
assertEquals(frame, stackFrames.next());
// b
frame = stackFrames.next();
ss = frame.getSourceSection();
assertSection(ss, "CALL(a)", 5, 3, 5, 9);
fss = getFunctionSourceSection(frame);
assertSection(fss, "ROOT(\n CALL(a))\n", 4, 10, 5, 11);
// root
frame = stackFrames.next();
ss = frame.getSourceSection();
assertSection(ss, "CALL(b)", 7, 1, 7, 7);
fss = getFunctionSourceSection(frame);
assertSection(fss, source.getCharacters().toString(), 1, 1, 7, 9);
assertFalse(stackFrames.hasNext());
event.prepareContinue();
});
expectDone();
}
}
use of com.oracle.truffle.api.debug.DebugStackFrame in project graal by oracle.
the class TruffleDebugger method createCallFrames.
private CallFrame[] createCallFrames(Iterable<DebugStackFrame> frames) {
List<CallFrame> cfs = new ArrayList<>();
int depth = 0;
for (DebugStackFrame frame : frames) {
SourceSection sourceSection = frame.getSourceSection();
if (sourceSection == null) {
continue;
}
if (frame.isInternal()) {
continue;
}
Source source = sourceSection.getSource();
if (source.isInternal()) {
// should not be, double-check
continue;
}
slh.assureLoaded(source);
Script script = slh.getScript(slh.getScriptId(source));
List<Scope> scopes = new ArrayList<>();
DebugScope dscope;
try {
dscope = frame.getScope();
} catch (Exception ex) {
PrintWriter err = context.getErr();
if (err != null) {
err.println("getScope() has caused " + ex);
ex.printStackTrace(err);
}
dscope = null;
}
String scopeType = "block";
boolean wasFunction = false;
SourceSection functionSourceSection = null;
while (dscope != null) {
if (wasFunction) {
scopeType = "closure";
} else if (dscope.isFunctionScope()) {
scopeType = "local";
functionSourceSection = dscope.getSourceSection();
wasFunction = true;
}
if (dscope.isFunctionScope() || dscope.getDeclaredValues().iterator().hasNext()) {
// provide only scopes that have some variables
scopes.add(createScope(scopeType, dscope));
}
dscope = getParent(dscope);
}
try {
dscope = ds.getTopScope(source.getLanguage());
} catch (Exception ex) {
PrintWriter err = context.getErr();
if (err != null) {
err.println("getTopScope() has caused " + ex);
ex.printStackTrace(err);
}
}
while (dscope != null) {
if (dscope.getDeclaredValues().iterator().hasNext()) {
// provide only scopes that have some variables
scopes.add(createScope("global", dscope));
}
dscope = getParent(dscope);
}
CallFrame cf = new CallFrame(frame, depth++, script, sourceSection, functionSourceSection, null, scopes.toArray(new Scope[scopes.size()]));
cfs.add(cf);
}
return cfs.toArray(new CallFrame[cfs.size()]);
}
use of com.oracle.truffle.api.debug.DebugStackFrame in project graal by oracle.
the class SLDebugTest method testStack.
@Test
public void testStack() {
final Source stackSource = slCode("function main() {\n" + " return fac(10);\n" + "}\n" + "function fac(n) {\n" + " if (n <= 1) {\n" + // break
" return 1;\n" + " }\n" + " return n * fac(n - 1);\n" + "}\n");
try (DebuggerSession session = startSession()) {
session.install(Breakpoint.newBuilder(getSourceImpl(stackSource)).lineIs(6).build());
startEval(stackSource);
expectSuspended((SuspendedEvent event) -> {
Iterator<DebugStackFrame> sfIt = event.getStackFrames().iterator();
assertTrue(sfIt.hasNext());
DebugStackFrame dsf = sfIt.next();
assertEquals("fac", dsf.getName());
assertEquals(6, dsf.getSourceSection().getStartLine());
assertFalse(dsf.isInternal());
int numStacksAt8 = 10 - 1;
for (int i = 0; i < numStacksAt8; i++) {
assertTrue(sfIt.hasNext());
dsf = sfIt.next();
assertEquals("fac", dsf.getName());
assertEquals(8, dsf.getSourceSection().getStartLine());
assertFalse(dsf.isInternal());
}
assertTrue(sfIt.hasNext());
dsf = sfIt.next();
assertEquals("main", dsf.getName());
assertEquals(2, dsf.getSourceSection().getStartLine());
assertFalse(dsf.isInternal());
// skip internal frames
while (sfIt.hasNext()) {
dsf = sfIt.next();
assertTrue(dsf.isInternal());
}
});
expectDone();
}
}
use of com.oracle.truffle.api.debug.DebugStackFrame in project graal by oracle.
the class SLDebugTest method testBreakpoint.
@Test
public void testBreakpoint() throws Throwable {
/*
* Wrappers need to remain inserted for recursive functions to work for debugging. Like in
* this test case when the breakpoint is in the exit condition and we want to step out.
*/
final Source factorial = slCode("function main() {\n" + " return fac(5);\n" + "}\n" + "function fac(n) {\n" + " if (n <= 1) {\n" + // break
" return 1;\n" + " }\n" + " return n * fac(n - 1);\n" + "}\n");
try (DebuggerSession session = startSession()) {
startEval(factorial);
Breakpoint breakpoint = session.install(Breakpoint.newBuilder(getSourceImpl(factorial)).lineIs(6).build());
expectSuspended((SuspendedEvent event) -> {
checkState(event, "fac", 6, true, "return 1", "n", "1");
checkArgs(event.getTopStackFrame(), "n", "1");
Iterator<DebugStackFrame> sfi = event.getStackFrames().iterator();
for (int i = 1; i <= 5; i++) {
checkArgs(sfi.next(), "n", Integer.toString(i));
}
// main
checkArgs(sfi.next());
assertSame(breakpoint, event.getBreakpoints().iterator().next());
event.prepareStepOver(1);
});
expectSuspended((SuspendedEvent event) -> {
checkState(event, "fac", 8, false, "fac(n - 1)", "n", "2");
checkArgs(event.getTopStackFrame(), "n", "2");
assertEquals("1", event.getReturnValue().as(String.class));
assertTrue(event.getBreakpoints().isEmpty());
event.prepareStepOut(1);
});
expectSuspended((SuspendedEvent event) -> {
checkState(event, "fac", 8, false, "fac(n - 1)", "n", "3");
assertEquals("2", event.getReturnValue().as(String.class));
assertTrue(event.getBreakpoints().isEmpty());
event.prepareStepOut(1);
});
expectSuspended((SuspendedEvent event) -> {
checkState(event, "fac", 8, false, "fac(n - 1)", "n", "4");
assertEquals("6", event.getReturnValue().as(String.class));
assertTrue(event.getBreakpoints().isEmpty());
event.prepareStepOut(1);
});
expectSuspended((SuspendedEvent event) -> {
checkState(event, "fac", 8, false, "fac(n - 1)", "n", "5");
assertEquals("24", event.getReturnValue().as(String.class));
assertTrue(event.getBreakpoints().isEmpty());
event.prepareStepOut(1);
});
expectSuspended((SuspendedEvent event) -> {
checkState(event, "main", 2, false, "fac(5)");
checkArgs(event.getTopStackFrame());
assertEquals("120", event.getReturnValue().as(String.class));
assertTrue(event.getBreakpoints().isEmpty());
event.prepareStepOut(1);
});
assertEquals("120", expectDone());
}
}
Aggregations