DBG(3)DBG(3)NAME
dbg - remote kernel debugging
SYNOPSIS
bind -b '#b' /dev
/dev/dbgctl
/dev/dbglog
echo r >/dev/dbgctl
DESCRIPTION
Dbg allows a native kernel to be debugged remotely, by means of a sim‐
ple protocol, typically run on a serial port (see eia(3)). The
acid(10.1) debugger uses the protocol for instance; see its -R option.
Dbg uses the values of several global variables set by the kernel con‐
figuration file (see conf(10.6)), all of which default values. The
variables and default values are listed below:
int dbgstart = 0;
char *dbgdata = "#t/eia0";
char *dbgctl = "#t/eia0ctl";
char *dbgctlstart = "b19200";
char *dbgctlstop = "h";
char *dbgctlflush = "f";
Different values can be set by including similar declarations, with
values as desired, in the code section of the configuration file. Dbg
uses the values as follows:
dbgstart if non-zero, start the debugger protocol on the configured
connection during driver initialisation (system startup);
otherwise it must be started explicitly by the r control
request (see below)
dbgdata data file for the debugging connection
dbgctl control file for the debugging connection
dbgctlstart control request to initialise link (eg, baud rate)
dbgctlstop control request to hang up link
dbgctlflush control request to write to flush input and output on link
Dbg serves two files that control and monitor its operation.
Dbgctl accepts several textual commands; normally only r is needed:
d dbgdata
set the value of dbgdata to the value given as an argument
c dbgctl
i dbgctlstart
h dbgctlstop
f dbgctlflush
set the value of the corresponding control variable to the value
of the first argument
r start running the debugger protocol (not needed if dbgstart was
non-zero at boot)
s stop running the debugger protocol; stop and flush the link
When read, dbgctl yields a single line showing the status of the device
(`running' or `stopped') and the current values of the debugger control
variables listed above.
Dbglog is a read-only text file containing lines representing debugger
events, one per line. It is mainly useful for checking the operation
of the device, or debugging new acid(10.1) functions.
Debug protocol
The protocol is subject to change. The host running the debugger and
the target to be debugged exchange 10-byte messages containing a one
byte message type and 9 bytes of data. Bytes unused by a given type
are set to zero. Normally the host sends one of the T-messages below
and receives the corresponding R-message, or Rerr. (These are unre‐
lated to the T-messages and R-messages of intro(5).) Exceptionally,
the target sends the first message, an Rerr to reset the protocol, and
thus the debugger is notified if the target is rebooted during a debug‐
ging session and can reset its own state. Values, including addresses,
are sometimes represented textually in hexadecimal, but are usually in
binary as a single byte, or an array of 4 bytes, high-order byte first
(big endian).
The term process here refers exclusively to those created directly or
indirectly by kproc(10.2), not to Limbo processes, which are not visi‐
ble directly through the protocol (although it is possible to write
acid(10.1) functions that interact through dbg with the Inferno data
structures representing the state of the Dis virtual machine). Many
requests read or write the memory or state of the current process set
by the Tproc message (see below). Addresses are always 32 bits. An
address below the size of Ureg (saved register state) for the target is
interpreted as an offset within the saved state for the current
process. Otherwise it refers to an address in kernel virtual memory.
Currently in native Inferno all processes share the same address space.
The message type names used below are assigned values by declarations
in /include/rdbg.h. The following messages are currently implemented:
Terr unused
Rerr reason[9]
The last message failed for the given reason, a text string:
reset, the target or debug driver was restarted; count, bad
count; unk, unknown command; inval, invalid parameter; pid, no
such process; unsup, unsupported action; notstop, action requires
process to be stopped first.
Tmget addr[4] n[1]
Request n bytes of memory from addr; n must be no greater than 9
Rmget data[9]
Return data requested by Tmget
Tmput addr[4] n[1] data[4]
Write the first n bytes of data to memory at addr, and flush the
data and instruction caches for that region; n must be no greater
than 4
Rmput Reply to a successful Tmput
Tproc pid[4]
Set the current process to the one with integer process ID pid
for subsequent requests.
Rproc addr[8]
Addr is the address in hexadecimal text of the Proc structure for
process pid in the corresponding Tproc.
Tstatus pid[4]
Request the status of process pid leaving the current process ID
unchanged.
Rstatus status[9]
Return the textual status of the process as a text string, cur‐
rently one of: Dead, Moribund, Ready, Scheding, Running, Queue‐
ing, Wakeme, Broken, Stopped, Rendezvous, or if invalid, the
state value as a hexadecimal number.
Trnote pid[4]
Retrieve the note (trap status) for the given pid
Rrnote status[9]
Provide the textual trap status for the requested process (cur‐
rently always returns null status)
Tstop pid[4]
Tell the kernel to stop running process pid in debugging state
Stopped when it next appears in the scheduler.
Rstop Reply to successful Tstop
Tstart
Cancel a previous Tstop; if the process has already stopped, make
it ready to run.
Rstart
Reply to successful Tstart
Tcondbreak val[4] op[4]
If op is d, remove and delete the breakpoint with ID val. All
other operations help create a conditional breakpoint, providing
a possibly empty list of operations representing a conditional
expression in Reverse Polish is followed by a breakpoint request,
each expression element represented by a single Tcondbreak mes‐
sage. Op is a single character representing an operation, with
val (integer, address, process ID) as a parameter. The operator
n should appear first; it assigns the breakpoint an ID number val
(no greater than 255). Expression primaries are: k val, true if
process val is at this breakpoint; b val, true if program counter
is val; and p val, val as a 32-bit literal. Expression operators
are: unary * (indirect, yielding 32-bit value); & (bit-wise AND);
= (values equal); ! (values not equal); a (logical AND); o (log‐
ical OR). Although the expression is interpreted following
Reverse Polish notation, when transmitted, the b operation is
sent last (to mark the end of the sequence and create the break‐
point), but is moved to the start of the expression before evalu‐
ation.
Rcondbreak
Reply to successful Tcondbreak.
Tstartstop pid[4]
If the process pid is not stopped, return Rerr notstop. Other‐
wise, if the process is not stopped at a breakpoint, start it,
and wait for it to reach a breakpoint that evaluates `true'
Rstartstop id[1]
Process has stopped at breakpoint with the given id
Twaitstop
Unimplemented. See Tstartstop.
Rwaitstop
Unused.
Tkill pid[4] note[5]
Kill process pid with the given textual note. Unimplemented.
Rkill Reply to successful Tkill. Unused.
SOURCE
/os/port/devdbg.c
/os/*/*break.c
/os/*/trap.c
SEE ALSO
acid(10.1)
BUGS
The protocol is not itself error-detecting let alone error-correcting,
although that normally does not matter for debugging even over a serial
line, provided the connection is reasonably sound.
DBG(3)