Introduction
scripts/pyro-debug/pyro_debug.py is an interactive readline client for
Pyromaniac's sysrq TCP server (sysrqserver.enable/sysrqserver.port).
The raw socket (usable directly with nc/telnet) is already most of a
CLI debugging interface: a line-based REPL with a help command listing
every registered sysrq, and human-readable formatting for dict/list/str
replies. pyro_debug.py adds the client-side polish that was missing:
- readline history (
~/.pyro_debug_history) and tab-completion over every registered sysrq name - short, gdb-style aliases for the debugging sysrqs reached for most
often (
b,c,s,bt- see below) - shell-style argument quoting, so a value containing spaces can be
passed as one argument (
sysvars-set MyVar$Test "Hello World") - implemented server-side, inpyromaniac.sysrq.server.dispatch_sysrq_command, so it benefits the raw socket and any other client too, not just this one
It needs no server-side capability beyond what already exists in
pyromaniac/sysrq/debug.py, watchpoints.py and tracepoints.py - see
PLANGDB.md Stage 8. It works against any Pyromaniac instance with
sysrqserver.enable=true, independently of the GDB stub
(docs/FEATURES.md's GDBStub section, PLANGDB.md) - the two are
separate clients of the same sysrq substrate, the same way the MCP
server (docs/PYROMCP.md) is.
Requirements
Python 3, with the standard library readline module available (present
on Linux/macOS by default; tab-completion and history fall back to plain
line editing if it isn't). No extra packages to install.
If you're working from a built/installed Pyromaniac archive (the one
crosscompile/Makefile's cross_install produces, alongside pyro,
pyro-server and pyro-client) rather than a source checkout, use the
pyro-debug command it ships instead of python3
scripts/pyro-debug/pyro_debug.py below - it's a thin wrapper that just
locates pyro_debug.py among the installed resources and hands off to
python3 (there's nothing to install, so unlike pyro-mcp it doesn't
need an environment of its own).
Usage
Start Pyromaniac with the sysrq server enabled:
pyro.py --config sysrqserver.enable=true ...
or, for a persistent instance:
pyro_server.py --config sysrqserver.enable=true ...
Then, from a separate terminal:
python3 scripts/pyro-debug/pyro_debug.py
Options:
| Flag / environment variable | Default | Meaning |
|---|---|---|
--host / PYRODEBUG_HOST |
127.0.0.1 |
Host to connect to |
--port / PYRODEBUG_PORT |
8809 |
sysrq server port (matches sysrqserver.port's own default) |
Type quit or exit (or Ctrl-D) to leave the session.
Aliases
| Alias | Expands to | Meaning |
|---|---|---|
b <address> |
tracepoints-add <address> break |
Set a breakpoint |
c |
debug-resume |
Continue execution |
s [count] |
debug-step into [count] |
Single-step (or count steps) |
bt |
debug-backtrace |
Show a backtrace, where available |
Any other input is sent to the sysrq server exactly as typed - the full
sysrq surface remains directly reachable by name (help lists them
all), the aliases are a convenience for the handful used constantly,
not a replacement for the rest.
Example session
$ python3 scripts/pyro-debug/pyro_debug.py
pyro-debug> debug-pause
True
pyro-debug> b 8030
True
pyro-debug> regs-list
R0: 0
R1: 0
...
pc: 32816
pyro-debug> c
True
pyro-debug> bt
available: True
lines: [...]
pyro-debug> watchpoints-add ff8 break
True
pyro-debug> quit
Relationship to the raw sysrq socket and other clients
pyro_debug.py is a thin client: every command it sends (after alias
expansion) is exactly what you would type against the raw socket with
nc/telnet directly, and every reply is formatted by the same
dispatch_sysrq_command() the socket has always used. It adds nothing
server-side beyond the argument-quoting fix noted above, and has no
dependency on the GDB stub or the MCP server - all three are independent
clients of the same sysrq substrate, useful in different contexts
(GDB for register/memory/breakpoint work through a real debugger's UI,
MCP for AI agent tool integration, this CLI for a quick interactive
session from a terminal).