Skip to main content
Version: Next (unstable)

TUI mode

The default mode renders a full-screen terminal UI with live source, disassembly, operand stack, call stack, and breakpoint panes. Launch it by running miden debug with a program path:

miden debug sum.masp

When the debugger starts, it stops at cycle 0 so you can set up breakpoints before the program runs.

Layout​

The home page is split into the following panes:

  • Source code — current instruction's source line with syntax highlighting, when source is available.
  • Disassembly — the five most recently executed VM instructions plus the cycle counter.
  • Stack trace — call frames, when the program was compiled with frame tracing (trace.240 / trace.252).
  • Operand stack — current contents and depth.
  • Breakpoints — active breakpoints and how many fired at this instruction.

Switch focus between panes with h / l (or the arrow keys).

Keyboard shortcuts​

KeyAction
qQuit the debugger
hFocus next pane
lFocus previous pane
sStep one VM cycle
nStep to the next instruction
cContinue until the next breakpoint or program end
eExit the current call frame (run until return)
dDelete the focused item (e.g. a breakpoint when the breakpoints pane has focus)
:Open the command prompt (see below)

In any pane that lists items or shows multiple lines (source, disassembly, breakpoints, stack trace), j / k (or up/down arrows) move the cursor.

Command prompt​

Press : to open the prompt. The footer shows what you type.

CommandAliasesEffect
:quit:qExit the debugger
:reload:r, :restartReload the program from disk and reset execution (breakpoints kept)
:debugShow the debugger's internal log (its own diagnostic stream)
:next-line:nl, :nextlineRun until the next source line is reached
:break SPEC:b, :breakpointCreate a breakpoint — see Breakpoints
:read EXPR:r EXPRInspect linear memory — see Reading memory
:vars [all]:variables, :localsShow source-level variables — see Inspecting variables
:where:p, :procPrint the procedure name at the current instruction (and at the focused frame, if it differs)

Typing an unknown command leaves the prompt and shows unknown command in the status line.

Breakpoints​

:break (alias :b, :breakpoint) accepts six expression forms:

ExpressionDescription
:b FILE[:LINE]Break when the current instruction's source location matches FILE (a glob, e.g. fib.masm or **/lib/*.masm) and, when given, exactly the line number.
:b in NAMEBreak when entering a procedure whose fully-qualified name matches the glob NAME (e.g. :b in std::math::*).
:b for OPCODEBreak when an instruction with the literal opcode OPCODE is about to execute (matched including immediates).
:b nextBreak on the next instruction boundary. One-shot.
:b after NBreak after N more cycles. One-shot.
:b at CYCLEBreak when the cycle counter reaches CYCLE. No-op if CYCLE already passed. One-shot.

:b finish is also accepted from the prompt; it's equivalent to the e shortcut and stops when the current call frame returns.

Hit breakpoints are highlighted in the breakpoints pane; the pane's lower right shows how many breakpoints triggered at the current cycle. One-shot breakpoints (next, after N, at CYCLE, finish) are removed once they fire.

To find a procedure name to plug into :b in ..., use :where — it prints the live procedure as well as the procedure of the focused frame.

Reading memory​

:read (alias :r) reads linear memory in a chosen format.

:r ADDR [OPTIONS..]

ADDR is decimal or 0x-prefixed hex.

OptionAliasValuesDefaultDescription
-mode MODE-mwords (word, w), bytes (byte, b)wordsAddress mode
-format FORMAT-fdecimal (d), hex (x), binary (bin, b)decimalOutput format for integers
-count N-cinteger1Number of units to read
-type TYPE-tsee belowwordType of value to read (sets default -format and unit size)

Types​

TypeMeaning
iNSigned integer of N bits
uNUnsigned integer of N bits
feltA field element
wordA Miden word (four field elements)
ptr, pointerA 32-bit memory address (forces -format hex)

Examples:

:r 0x1000                  # one word in decimal
:r 0x1000 -t felt # one field element
:r 0x1000 -t u32 -c 4 -f x # four u32 values in hex

Inspecting variables​

:vars (aliases :variables, :locals) renders source-level variables resolved from DWARF info embedded in the program for the selected physical stack frame. Suspended callers retain their own declarations, captured stack values, and frame bases; memory reads use the owning invocation's context. Inline frames do not yet expose separate locals or lexical scopes.

By default the output hides compiler-generated locals (named local0, local1, …) so you only see the names that appear in the original source. Add all to include the compiler locals:

:vars       # source-level variables only
:vars all # also include compiler-generated locals

When the program has no DWARF info, :vars prints No debug variables tracked. When it has DWARF but every variable is compiler-generated, you'll see No source-level variables (use ':vars all' to show compiler locals).

After successful termination, variable commands report Program has terminated; no live variables. Final stack outputs remain available, and variables from a failed execution remain inspectable.

Each variable is rendered as name=value. If its storage cannot be read, the value is shown as <unavailable>.

Tips​

  • The TUI honours --color always / --color never if your terminal lies about its colour support.
  • MIDENC_TRACE=miden_debug=debug miden debug ... writes the debugger's own log to stderr; combined with :debug from the prompt this is the fastest way to diagnose unexpected behaviour.
  • Breakpoints survive :reload; only the program state and cycle counter reset.