Example: debugging

Techniques for debugging Quadrate programs.

Stack debugging

Use the built-in debug instructions to inspect stack state:

fn main() {
    1 2 3
    prints    // 1 2 3 (print entire stack, non-destructive)
    printsv   // int:1 int:2 int:3 (with type info)
    printv    // int:3 (print and pop top value)
    prints    // 1 2
    drop drop
}
Instruction Pops Type info Description
prints No No Print entire stack
printsv No Yes Print entire stack with types
printv Yes (one) Yes Print and pop top value

GDB debugging

Quadrate supports source-level debugging with GDB. Compile with -g to include debug symbols:

quadc -g -o myprogram myprogram.qd
gdb ./myprogram

Setting breakpoints

Break at a specific line in your .qd source:

(gdb) break myprogram.qd:10
(gdb) run

Inspecting the stack

Use the runtime debug helper to print the full stack:

(gdb) call (void)qd_debug_print_stack(ctx)
(gdb) print qd_context_stack_size(ctx)

For low-level inspection, the internal stack structure is also accessible:

(gdb) print ctx->st->size
(gdb) print ctx->st->data[0]

Stepping through code

Standard GDB commands work with Quadrate source files:

(gdb) next       # Step over
(gdb) step       # Step into
(gdb) continue   # Resume execution
(gdb) list       # Show source around current line

Compiler diagnostics

Dump tokens

See how the lexer tokenizes your source:

quadc --dump-tokens myprogram.qd

Dump AST

See the parsed abstract syntax tree:

quadc --dump-ast myprogram.qd

Dump LLVM IR

Inspect the generated LLVM intermediate representation:

quadc --dump-ir myprogram.qd

Verbose compilation

Show detailed compilation information:

quadc --verbose myprogram.qd