NAME
struct febug_message
,
struct stop_febug_message
, struct
attn_febug_message
—
User-space debugfs ABI
SYNOPSIS
#include
<febug-abi.h>
struct febug_message;
struct stop_febug_message;
struct attn_febug_message;
DESCRIPTION
The febug ABI consists of two messages sent from the program wishing to be debugged to febug(8), and one sent from febug(8) to the program.
To be debugged, the program must create a socket with
socket(AF_UNIX, SOCK_SEQPACKET, 0)
and
connect(2) to the appropriate end-point
(/var/run/febug.sock, conventionally). The
filesystem will then immediately acquire effective credentials from the
client. After febug(8) receives credentials, a directory corresponding to the
debugged process' PID will be created in the filesystem.
All messages must be sent in a single send(2) or sendmsg(2) call, specifying the exact size of the message, as that's what's used to differentiate between different messages. febug(8) will ignore messages (whose sizes) it does not recognise.
Afterward, for each variable of interest, the process should send
a 4096-byte febug_message
, defined as follows:
struct [[packed]] febug_message { uint64_t variable_id; uint64_t variable_type; uint8_t signal; char name[/* Enough to bring the overall size to 4096. */]; };
- variable_id
- is the locally unique identifier of the variable (e.g. a pointer to that variable).
- variable_type
- is arbitrary user data, passed back to the program verbatim (e.g. a function pointer to a formatter).
- signal
- is the signal to send to the program when a variable is to be read (see below).
- name
- is the globally unique name of this variable — a NUL terminator is respected but not required if the name truly spans to the final byte. If the same as one of the already-present variables, it will be overridden.
When febug(8) receives a febug_message
, it creates
a file under the process' directory. When that file is opened,
febug(8)
will:
- send the process an
attn_febug_message
with a single file descriptor viaSCM_RIGHTS
auxilliary data (see cmsg(3)) representing the write end of a pipe. - kill(2) the process with the signal from the
signal field if it wasn't
SIGKILL
.
Note, that the sent file descriptor must be closed by the program when it's done serialising the variable, and therefore, if the process opts not to receive a signal, it must handle the message through some other mechanism.
attn_febug_message
is 16 bytes, and
defined as follows:
struct [[packed]] attn_febug_message { uint64_t variable_id; uint64_t variable_type; };
febug_message
that installed the variable.
The process may receive any number of
attn_febug_message
s until it sends an 8-byte
stop_febug_message
, defined as follows:
struct [[packed]] stop_febug_message { uint64_t variable_id; };
When the process' end of the socket is closed, all extant variables are freed, and the process' directory is removed.
SEE ALSO
libfebug(3), libfebug++(3), and libfebug.rs(3) — libraries that wrap this ABI.
SPECIAL THANKS
To all who support further development, in particular:
- ThePhD
- Embark Studios
- Lars Strojny
- EvModder
REPORTING BUGS
febug mailing list: <~nabijaczleweli/febug@lists.sr.ht>, archived at https://lists.sr.ht/~nabijaczleweli/febug