CLI command reference
viewalyzer-cli <command> [flags], or viewalyzer --headless [flags] for the flag form. viewalyzer-cli help prints this list with every connection key. The binary ships inside the ViewAlyzer app package and next to it in the BKPT Debug extension; the Python SDK finds it through the VIEWALYZER environment variable, then PATH, then the install locations.
Commands
| COMMAND | WHAT IT DOES |
|---|---|
capture | Record a trace to a .vadb (or a .va byte-log). --config, --transport, --output, --duration, --stop-file, --stream, --elf, --keep-va, --no-register, the instrument flags. Capture and stream |
snapshot | Read the firmware's RAM ring through the probe without a reset, save it as a recording. Same connection flags, --output |
poll | Sample variables over the probe at a fixed rate, no firmware instrumentation: --elf, --symbols a[:u16],0xADDR[:u32][:name], --poll-hz, --duration-s, --stream, --coalesce-gap |
reset | Reset the target behind the configured probe |
load <file> | Load a .vadb, .va or raw wire dump and print its summary; --output x.vadb converts, --export events|traces|spans|tasks|channels --format json|csv --out file|- exports |
query <verb> | Pre-shaped JSON views of a recording, including task-states, resources, queue-failures and semaphores with actor-ID filters. Queries |
import <rec> --series f.ndjson | Merge an external instrument's samples (a power analyser, a DAQ) into a recording with sync-mark alignment |
replay <rec> [--perf] | Re-parse a recording and print [metric] category,name,value,unit lines, a stable machine-parseable surface for CI harnesses; --perf adds pipeline timings |
hwtrace --dry-run | The hardware-trace register image for a core without a target: --arch v7m|v8m|v6m --caps '{...}' --cpu-clock-hz N --swo-freq-hz N --itm-port P --hardware-trace <json|@file>. Capture and stream |
probes | Connected debug probes with serials |
ports | Serial ports |
targets [--filter s] | probe-rs target names (STM32G474RE and 3800 others) |
recordings | The recording index; --delete-recording <id>, --delete-all-recordings |
symbols --elf f [--filter s] | Pollable data symbols of a firmware image, with address, size and inferred type |
memory --elf f [--map f] | Flash and RAM usage by section; with the linker map, region capacities and discarded sections |
callgraph --elf f [--root fn] [--depth n] [--direction out|in|both] [--entries] | Static call graph decoded from the image's code, no toolchain needed |
config --config f [flags] | Echo the effective connection configuration without touching hardware |
doctor | Environment report: probes per kind, serial ports, directories, target registry, license, caps_in_effect, caps_source (free, license, or none), and effective_caps. Always exits 0 |
license [get|activate <key>|validate|deactivate|install <file>] | License state and lifecycle. get is local; the others are the only online calls |
version | {schema_version, app, version, core, edition, transports[], license{}} |
The flag form
| VERB FORM | FLAG FORM |
|---|---|
capture --config b.vacf --output run.vadb --duration 10 | viewalyzer --headless --config b.vacf --output run.vadb --duration 10 |
probes | --headless --list-probes |
snapshot --config b.vacf --output crash.vadb | --headless --snapshot --config b.vacf --output crash.vadb |
query timeline --recording <id> --tier summary | --headless --query timeline --recording <id> --tier summary |
poll ... | --headless --record-polls ... |
replay run.vadb --perf | --headless --replay run.vadb --perf |
recordings | --headless --list-recordings |
memory --elf f | --headless --analyze-memory --elf f |
symbols --elf f | --headless --list-symbols --elf f |
license get | --headless --get-license (and --activate-license KEY, --validate-license, --deactivate-license, --install-license FILE) |
version | --headless --version |
Connection keys
The same names work as flags (--key value) and as keys in a .vacf JSON file (--config); flags win over the file. Unknown keys are errors; comment and _* keys are notes.
| KEY | MEANING |
|---|---|
transport | stlink-swo, stlink-rambuf, stlink-rtt, jlink-swo, jlink-rtt, jlink-rambuf, udp, serial, swo-tcp |
target-device | probe-rs target name (targets --filter lists them); empty lets the probe auto-detect |
interface | SWD (JTAG is accepted and SWD used) |
speed-khz | SWD clock (a J-Link is capped at 4000 through probe-rs) |
stlink-serial, jlink-serial | Pin a probe when several are attached; with several and no serial the capture refuses rather than guess |
no-reset | true attaches without resetting; default false resets after attach and captures from boot |
cpu-clock-hz | Core clock in Hz: required when the CLI programs direct SWO, optional for swo-tcp recorder streams whose CLK: setup supplies the recording clock (trace-clock-hz when the trace clock differs) |
swo-freq-hz | SWO rate in Hz; 2000000 is the value every probe takes, a STLINK-V3 goes to 24 MHz. It must divide the core clock in whole numbers |
itm-port | ITM stimulus port the recorder stream rides (default 1) |
init-swo | true (default): the host programs the ITM and TPIU on connect |
rtt-channel, rtt-address | RTT up-channel index (default: the channel named ViewAlyzer, else 0); _SEGGER_RTT address to skip the scan |
rambuf-address, rambuf-scan-start, rambuf-scan-size, rambuf-poll-ms | The _VA_RAMBUF control block (skips the scan); the RAM scan window (default 0x20000000, 128 KB); the idle poll interval (5 ms) |
udp-ip, udp-port, serial-port, baud, cobs | The socket and serial transports; cobs defaults to true for both |
swo-tcp-port, swo-tcp-host | A simulator or debug server's raw-SWO side channel (127.0.0.1) that the swo-tcp transport decodes |
jlink, jlink-engine | SEGGER install directory; auto | segger-dll | probe-rs |
dwt, dwt-exc, dwt-pc, dwt-watch, dwt-counters, dwt-path, itm-ports, itm-privilege, itm-timestamps, hardware-trace | Hardware trace, see Capture and stream |
--elf <firmware.elf> on capture, snapshot and poll pins the control block from the image (_VA_RAMBUF, _SEGGER_RTT) instead of scanning RAM, and names the polled symbols.
Older tool-path and server-port keys (jlink, arm-gdb, *-port, stlink) are accepted and reported as "no effect": the native probe drivers spawn no servers.
Output conventions
| CHANNEL | CONTENTS |
|---|---|
| stdout | Query and list commands: exactly one JSON object. capture, snapshot, poll: human progress lines, the contract lines below, then one JSON envelope as the last line |
| stderr | --stream JSON lines during a capture or a poll |
| exit code | 0 success, 1 failure (an error envelope is still printed). query compare exits 2 for a regression; hwtrace exits 2 on a configuration error |
The two lines hosts parse:
[headless] Recording saved: D:/tmp/run.vadb (2848 KB)
[headless] Recording registered: id=328d49aa4eb6
[headless] ERROR: ... precedes any failure. [headless] State: ..., [headless] t=... events ... and [capture] ... are progress, not contract.
Errors are one envelope:
{ "schema_version": 2, "error": "window_too_wide",
"message": "634 events in the window exceed the 200 row cap for budget low",
"suggestion": { "t_end_us": 31545, "or": "filter with --kinds, or raise --budget" },
"limits": { "max_rows": 200, "would_return_rows": 634 } }
Codes: bad_arguments, bad_config, no_such_recording, bad_recording, window_too_wide, bad_sql, empty_capture, capture_failed, snapshot_failed, empty_snapshot, reset_failed, cooldown_active (with retry_after_s), license_file_rejected, no_hw_trace, etm_not_present, symbol_not_found, map_not_found, internal.
Recordings and the index
A recording is one SQLite file. Any command that takes --recording accepts a path or the 12-hex recording_id; recordings lists {recording_id, path, schema_name, duration_us, size_bytes, created_utc} for every registered file that still exists, and the id is a stable hash of the absolute path and mtime. The index lives at <app dir>/recordings/index.json (%APPDATA%\ViewAlyzer-GPUI, ~/Library/Application Support/ViewAlyzer-GPUI, ~/.config/ViewAlyzer-GPUI); hosts that manage their own files pass paths and --no-register.
Utilities in practice
$ viewalyzer-cli version
{"schema_version":2,"app":"ViewAlyzer","version":"1.1.0","core":"rust","edition":"full","transports":["stlink-swo","stlink-rambuf","stlink-rtt","jlink-swo","jlink-rtt","jlink-rambuf","udp","serial","swo-tcp"],"license":{"type":"key","tier":"solo","licensed":true}}
$ viewalyzer-cli targets --filter STM32G474
{"schema_version":2,"filter":"STM32G474","count":18,"targets":[{"name":"STM32G474CB","architecture":"arm"}, ...]}
$ viewalyzer-cli config --config nucleo_g474_rambuf.vacf --stlink-serial 0033004B3033510735393935
{"schema_version":2,"config":{"transport":"stlink-rambuf","target-device":"STM32G474RE","interface":"SWD","speed-khz":24000,"no-reset":false,"stlink-serial":"0033004B3033510735393935","rambuf-scan-start":536870912,"rambuf-scan-size":131072},"describe":"stlink-rambuf target STM32G474RE cb 0x00000000 scan 0x20000000+0x20000 reset=true","probe_spec":"stlink:0033004B3033510735393935","capture_error":null,"notes":[]}
$ viewalyzer-cli symbols --elf firmware.elf --filter uwTick
{"schema_version":2,"symbol_legend":[{"name":"uwTick","address":"0x20000058","size":4,"type":"i32"}, ...],"data_symbols":3,"text_symbols":0}
$ viewalyzer-cli memory --elf firmware.elf
{"schema_version":2,"text":6816,"data":16,"bss":11016,"total":17848,"flash_used":6832,"ram_used":11032,"sections":[{"name":".text","address":"0x080001D8","size":6056,"category":"flash"}, ...]}
$ viewalyzer-cli doctor
{"schema_version":2,"app_version":"1.1.1","caps_in_effect":true,"caps_source":"free","effective_caps":{"max_recording_seconds":5,"max_visible_lanes":10,"cooldown_seconds":5,"max_poll_hz":100,"max_poll_symbols":4},"checks":[{"id":"probes_stlink","status":"ok","detail":"0033004B3033510735393935"},{"id":"probes_jlink","status":"none"},{"id":"serial_ports","status":"ok","detail":"COM29"},{"id":"recordings_dir","required":true,"status":"ok","path":"..."},{"id":"probe_rs_targets","status":"ok","detail":"3891 targets"},{"id":"license","status":"free","caps_in_effect":true,"caps_source":"free","caps":{"max_recording_seconds":5,"max_visible_lanes":10,"cooldown_seconds":5,"max_poll_hz":100,"max_poll_symbols":4}}]}
doctor is the first thing to run on a new machine: it exits 0 whatever it finds and names what is missing.
Validate a custom Trace Domain
viewalyzer-cli parse-trace-domain my-domain.vadomain --pretty
viewalyzer --headless --parse-trace-domain my-domain.vadomain --pretty
viewalyzer-cli parse-trace-domain --schema
This offline check uses the same parser as the applications. No SDK, probe or target connection is required. Pass one or more filenames; JSON output includes schema_version, domain_api, valid, and a files array with per-file results. Errors name the precise path, JSON Pointer pointer and message; syntax errors include line and column. Exit status is 0 for valid files, 1 for rejected content, or 2 for unreadable files or invalid arguments. Batch validation checks every file; status 2 takes precedence over 1. The --schema form takes no files and returns the structural schema in the response's schema property. Complete validation also checks semantic constraints and references.
See Creating custom Trace Domains for the full format, steps, examples and the optional Python SDK wrapper.