Give DebugBreakpointNode some section to prevent NPE (#11594)

Fixes `NullPointerException` by giving `DebugBreakpointNode` a source section.
This commit is contained in:
Jaroslav Tulach 2024-11-20 16:20:10 +01:00 committed by GitHub
parent 04075c5ed7
commit b3588490db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 3 deletions

View File

@ -317,6 +317,41 @@ public class DebuggingEnsoTest {
} }
} }
@Test
public void testEvaluateExpressionInDebugBreakpoint() {
Value fooFunc =
createEnsoMethod(
"""
import Standard.Base.Runtime.Debug
foo x =
a = 6
b = 7
Debug.breakpoint
""",
"foo");
int[] res = {0};
try (DebuggerSession session =
debugger.startSession(
(SuspendedEvent event) -> {
switch (event.getSourceSection().getCharacters().toString().strip()) {
case "Debug.breakpoint" -> {
DebugStackFrame stackFrame = event.getTopStackFrame();
DebugValue evaluatedValue = stackFrame.eval("a * b");
assertTrue(evaluatedValue.isNumber());
assertEquals(42, res[0] = evaluatedValue.asInt());
}
}
event.getSession().suspendNextExecution();
})) {
session.suspendNextExecution();
fooFunc.execute(0);
}
assertEquals("Really suspended at 42", 42, res[0]);
}
@Test @Test
public void testRewriteLocalVariable() { public void testRewriteLocalVariable() {
Value fooFunc = Value fooFunc =

View File

@ -8,6 +8,8 @@ import com.oracle.truffle.api.instrumentation.InstrumentableNode;
import com.oracle.truffle.api.instrumentation.ProbeNode; import com.oracle.truffle.api.instrumentation.ProbeNode;
import com.oracle.truffle.api.instrumentation.Tag; import com.oracle.truffle.api.instrumentation.Tag;
import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.CallerInfo; import org.enso.interpreter.runtime.callable.CallerInfo;
@ -20,6 +22,13 @@ import org.enso.interpreter.runtime.state.State;
autoRegister = false) autoRegister = false)
@GenerateWrapper @GenerateWrapper
public abstract class DebugBreakpointNode extends Node implements InstrumentableNode { public abstract class DebugBreakpointNode extends Node implements InstrumentableNode {
private static final SourceSection DEBUG_SECTION;
static {
var src = Source.newBuilder("enso", "Debug.breakpoint", "Debug.enso").build();
DEBUG_SECTION = src.createUnavailableSection();
}
/** /**
* Creates a new instance of this node. * Creates a new instance of this node.
* *
@ -29,13 +38,18 @@ public abstract class DebugBreakpointNode extends Node implements Instrumentable
return DebugBreakpointNodeGen.create(); return DebugBreakpointNodeGen.create();
} }
@Override
public final SourceSection getSourceSection() {
return DEBUG_SECTION;
}
/** /**
* Tells Truffle this node is instrumentable. * Tells Truffle this node is instrumentable.
* *
* @return {@code true} this node is always instrumentable. * @return {@code true} this node is always instrumentable.
*/ */
@Override @Override
public boolean isInstrumentable() { public final boolean isInstrumentable() {
return true; return true;
} }
@ -55,7 +69,7 @@ public abstract class DebugBreakpointNode extends Node implements Instrumentable
* @return {@code true} if the tag is {@link DebuggerTags.AlwaysHalt}, {@code false} otherwise * @return {@code true} if the tag is {@link DebuggerTags.AlwaysHalt}, {@code false} otherwise
*/ */
@Override @Override
public boolean hasTag(Class<? extends Tag> tag) { public final boolean hasTag(Class<? extends Tag> tag) {
return tag == DebuggerTags.AlwaysHalt.class; return tag == DebuggerTags.AlwaysHalt.class;
} }
@ -66,7 +80,7 @@ public abstract class DebugBreakpointNode extends Node implements Instrumentable
* @return the wrapper instance wrapping both this and the probe node * @return the wrapper instance wrapping both this and the probe node
*/ */
@Override @Override
public WrapperNode createWrapper(ProbeNode probeNode) { public final WrapperNode createWrapper(ProbeNode probeNode) {
return new DebugBreakpointNodeWrapper(this, probeNode); return new DebugBreakpointNodeWrapper(this, probeNode);
} }
} }