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
| Option | Description |
|---|---|
--box BOX | Lagerbox name or IP address (uses the default box if omitted) |
--type ROLE | Net role. Defaults to auto, which looks up the net’s role from the box’s saved nets. Pass an explicit role (battery, power-supply, scope, debug, usb, adc, …) to override, or to diagnose a net that isn’t saved. A debug net routes to the J-Link path. |
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):| Classification | Trigger |
|---|---|
HOST-SIDE: usbtmc kernel module loaded | the usbtmc kernel module is bound (run lager update to install the blacklist) |
HOST-SIDE: USB device claimed by multiple processes | VISA busy and two or more holders in lsof |
HOST-SIDE: USB device busy | VISA busy with a single holder |
TRANSIENT: device disappeared from USB | VISA nodev (re-enumeration) |
INSTRUMENT WEDGED | VISA timeout — enumerates and opens, but won’t answer *IDN? |
NOT ENUMERATED | the device does not show up on USB (check power/cable) |
HEALTHY | *IDN? returned (IDN string shown) |
HEALTHY (shared session) | the open was skipped because hw_service holds an active session |
TRANSIENT: enumerated as USB-TMC but fresh open failed | USB-TMC class but the fresh pyvisa open failed |
NOT USB-TMC | a vendor-SDK instrument (LabJack/LJM, Picoscope, Acroname, …), not pyvisa |
UNCLEAR | fallback — review the per-section output |
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
| Classification | Trigger |
|---|---|
HEALTHY: J-Link connected to <device> | target connect succeeded (core, and VTref when J-Link reports it) |
HEALTHY: J-Link gdbserver running | a gdbserver is up, listening, and its log is clean (active debug session) |
J-LINK SOFTWARE MISSING on box | the SEGGER J-Link tools aren’t installed (lager update installs them) |
PROBE NOT ON USB | the probe isn’t enumerated — check cable, probe power, upstream hub port |
PROBE CLAIMED | probe is on USB but JLinkExe can’t see it because another process holds it (usually a stale gdbserver — lager debug <net> disconnect) |
PROBE WEDGED | probe is on USB but JLinkExe enumeration is empty — power-cycle the probe |
GDBSERVER WEDGED | server process is up but its log shows a target-connection failure |
TARGET UNPOWERED | probe is fine but VTref is too low — the target board has no power on the debug header (or VTref isn’t wired) |
TARGET LOCKED | debug access is blocked by readout/IDCODE/AP protection — a mass-erase/unlock is required (e.g. nrfjprog --recover) |
DEVICE NAME | JLinkExe rejected the configured device — fix the net’s device/MCU field |
NO TARGET COMMS | probe + target power OK but SWD/JTAG connect failed — check SWDIO/SWCLK wiring, nRST pull-up, SWD-vs-JTAG, try a lower speed |
INCONCLUSIVE / UNCLEAR | connect probe was skipped or returned an unrecognized class — review the section output and rerun |
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

