Skip to content
bizzehdee edited this page Jun 23, 2026 · 2 revisions

Debugger

DScript has a built-in step debugger. Attach an IDebugger implementation to receive pause events and control execution.

IDebugger interface

using DScript.Debugger;

public interface IDebugger
{
    DebugAction OnPause(DebugEvent ev);
}

OnPause is called every time execution pauses (at a new source line, on entry to a function, or at a breakpoint). Return a DebugAction to continue.

DebugEvent

Property Type Description
Location SourceLocation Current source file, line, and column
CallStack IReadOnlyList<StackFrame> Stack frames from innermost to outermost

Each StackFrame has:

Property Description
FunctionName Name of the function ("<main>" for top-level code)
Locals IReadOnlyList<(string Name, string Value)> — local variable names and display values

DebugAction

Value Description
DebugAction.StepIn Execute one statement, stepping into calls
DebugAction.StepOver Execute one statement, skipping over calls
DebugAction.StepOut Run until the current function returns
DebugAction.Continue Run until the next breakpoint

Attaching and detaching

var debugger = new MyDebugger();

engine.AttachDebugger(debugger, initialAction: DebugAction.Continue);
engine.Run(program);
engine.DetachDebugger();

initialAction sets the action used before the first pause event.

Breakpoints

engine.AddBreakpoint("<main>", 10);   // break at line 10 of top-level code
engine.AddBreakpoint("helper.ds", 5); // break at line 5 of a module
engine.RemoveBreakpoint("<main>", 10);
engine.ClearBreakpoints();

Full example

using DScript;
using DScript.Debugger;

class TracingDebugger : IDebugger
{
    public DebugAction OnPause(DebugEvent ev)
    {
        var loc = ev.Location;
        Console.WriteLine($"→ {loc.Source}:{loc.Line}");

        var frame = ev.CallStack[0];
        foreach (var (name, value) in frame.Locals)
            Console.WriteLine($"    {name} = {value}");

        return DebugAction.StepIn;
    }
}

var engine = new ScriptEngine();
new EngineFunctionLoader().RegisterFunctions(engine);

engine.AttachDebugger(new TracingDebugger(), DebugAction.StepIn);
engine.AddBreakpoint("<main>", 1);

engine.Run(ScriptEngine.Compile(@"
    var x = 1;
    var y = x + 1;
    var z = x + y;
"));

engine.DetachDebugger();

See also

For performance measurement rather than step-by-step inspection, use the Profiler — it attaches alongside the debugger and produces V8-compatible .cpuprofile files viewable in Chrome DevTools and VS Code.

Language Server integration

The DScript.LanguageServer project provides an LSP server that uses the same debugger infrastructure. It supports VS Code's Debug Adapter Protocol for interactive debugging inside an editor. See the vscode-dscript/ extension for the client configuration.

Clone this wiki locally