lager diagnose <net> --box <box> [--type <role>] is a single-shot diagnosis for
a misbehaving instrument net. It collapses the manual debug workflow (lsof,
dmesg, bare pyvisa probes, hardware-service introspection) into one CLI call
that returns an actionable classification — host-side, instrument-wedged, or
healthy.
Introduced in lager 0.20.0 for USB-TMC (pyvisa) instruments. Extended in
0.28.3 to diagnose
debug nets (SEGGER J-Link, and a basic OpenOCD/ST-Link
path) — see Debug nets (J-Link) below.Syntax
Options
NET is the name of the net to diagnose (e.g. battery1, supply1).
Usage
Output sections
USB (host-side)
FromGET /diagnose/usb on box port 9000. Reports:
enumerated— does the device show up on the host’s USB bus?sysfs— kernel sysfs path (e.g./sys/bus/usb/devices/1-4).device—/dev/bus/usb/BBB/DDDpath used bylsof/fuser.usbtmc— whether theusbtmckernel module is loaded (and therefore racing libusb for interface 0).lsof—command(pid)list of processes holding the USB device file.dmesg tail— last few USB / usbtmc kernel messages.
VISA (instrument-side)
FromGET /diagnose/visa on box port 9000. Opens a fresh pyvisa session and
queries *IDN? with a short timeout. Skips the open (with a clear note) if the
hardware service already holds a shared session for this address — collisions
would either hang or return garbage. Reports:
idn— the IDN string if the instrument answered.elapsed— wall-clock ms.error/error_class— classified asbusy,nodev,timeout, orother.skipped— set when the hardware service holds the address.
Dispatcher (hw_service in-process)
FromGET /diagnose/dispatcher on hardware-service port 8080. Reports the
in-process state for this address:
cached_session— whether the sharedpyvisasession pool has it.cached_drivers— driver instances cached against this address.shared_pool— total pool size.
Classifications
The decision tree, in order (first match wins):Sample session
lager diagnose points you at the role-specific command instead of returning a
misleading UNCLEAR.
Debug nets (J-Link)
Adebug net isn’t USB-TMC, so the pyvisa *IDN? probe above can’t reach it.
When the net’s role is debug (auto-detected, or forced with --type debug),
lager diagnose takes a J-Link-aware path instead: it fetches the same
host-side USB section plus a dedicated /diagnose/jlink endpoint and walks
the debug stack outside-in — software → USB → probe-visible → gdbserver →
target connect — so the most specific actionable fault wins.
J-Link / debug probe section
In addition to the USB (host-side) section, a debug net prints a J-Link / debug probe section reporting:backend— the probe backend (jlink, or an OpenOCD/ST-Link backend).jlink software— whether the SEGGER J-Link tools are installed on the box.probe enum— does the probe show up on the host’s USB bus?probe visible— doesJLinkExeactually enumerate the probe (with the emulator product/serial list)?holders—command(pid)of any process holding the probe (usually a stale gdbserver).gdbserver— whether a J-Link gdbserver is running, its PID, and whether its logfile looks healthy.connect— the result of a target-connect probe:connect_ok, an error class,VTref(target reference voltage), and the detectedcore. The rawJLinkExeoutput is shown when the failure can’t be classified.
openocd-basic section (backend, probe enumeration, and
gdbserver state) — deep target diagnosis is J-Link-only for now.
Debug classifications
Sample debug session
Backwards compatibility
Against a pre-0.20 box, each endpoint returns 404 and the CLI notes that the section is unavailable (the box may be on a lager < 0.20 image). The remaining sections still run —lager diagnose is useful against an older box, just less
informative.
See Also
- Instruments — list attached instruments and their VISA addresses
- Nets — list saved nets and their roles
- Debug — connect, flash, and gdbserver control for debug nets
- Hello — basic box-side connectivity and version check

