LIBFEBUG.RS(3) | FreeBSD Library Functions Manual | LIBFEBUG.RS(3) |
febug::start()
,
febug::Wrapper
,
febug::Wrappable
,
febug::StaticWrappable
,
febug::GLOBAL_CONTROLLED_SOCKET
,
febug::FORMATTERS
—
User-space debugfs ABI wrapper library for Rust
[dependencies] febug = "1.0.0-1-g3324bf81"
env!("FEBUG_DONT")?
env!("FEBUG_SOCKET") =
"/var/run/febug.sock"
env!("FEBUG_SIGNUM") = SIGUSR2
env::var
("FEBUG_DONT"
);
env::var
("FEBUG_SOCKET"
);
static GLOBAL_CONTROLLED_SOCKET:
AtomicI32 =
-1;
fn febug::start
();
fn
febug::start_raw
(path:
&[u8]);
extern "C" fn
debug_handler
(_:
c_int);
bool fn
febug::install_handler
();
bool fn
febug::install_handler_signal
(signal:
u8);
fn febug::end
();
struct
Type(u64);
impl
From<TypeId>
for
Type;
impl
From<u64>
for
Type;
static febug::FORMATTERS:
Lazy<Mutex<BTreeMap<TypeId, fn(&mut File,
usize)>>>;
trait febug::StaticWrappable: 'static;
Wrapper<Self> fn
febug::StaticWrappable::wrap
(&self,
name:
Arguments<'_>);
Wrapper<Self> fn
febug::StaticWrappable::wrap_signal
(&self,
signal: u8,
name:
Arguments<'_>);
trait febug::Wrappable;
Wrapper<Self> fn
febug::Wrappable::wrap
(&self,
tp: u64,
name:
Arguments<'_>);
Wrapper<Self> fn
febug::Wrappable::wrap_signal
(&self,
tp: u64,
signal: u8,
name:
Arguments<'_>);
struct febug::Wrapper<T> { /* …
*/ }
;
Wrapper<T> fn
febug::Wrapper::new
(&self,
tp: u64,
data:argument,
name: fmt::Arguments,
name:
Arguments<'_>);
Wrapper<T> fn
febug::Wrapper::new_signal
(&self,
tp: u64,
data:argument,
signal: u8,
name: fmt::Arguments,
name:
Arguments<'_>);
struct febug::abi::FebugMessage;
struct febug::abi::StopFebugMessage;
struct febug::abi::AttnFebugMessage;
Simplifies writing Rust programs debuggable with febug(8) by presenting a high-level interface to febug-abi(5).
There are three compile-time environment variables that allow
customising libfebug.rs
behaviour:
FEBUG_DONT
FEBUG_SIGNUM
febug_wrap
().
Defaults to SIGUSR2
.FEBUG_SOCKET
There are two environment variables that allow a user to customise its behaviour:
FEBUG_DONT
FEBUG_SOCKET
FEBUG_SOCKET
to connect to
febug(8).To be debugged, a program needs to, first,
call
febug::start_raw
()
(likely via
febug::start
(),
which simply passes b"/var/run/febug.sock"
thereto) to connect to febug(8),
which, if successful, will set
febug::GLOBAL_CONTROLLED_SOCKET to the connection's
file descriptor.
The program needs to install
febug::debug_handler
()
(or a wrapper around it) as the signal handler for
FEBUG_SIGNUM
(and any other signals, if different
ones are explicitly requested); if notifications are disabled (by requesting
SIGKILL
), some event loop that answers on
febug::GLOBAL_CONTROLLED_SOCKET must be in place. It's
a no-op if febug::GLOBAL_CONTROLLED_SOCKET is
-1. A convenience
febug::install_handler
()
function is provided, doing just that, and returning
true if
the handler was installed.
The program should register handlers
for types of variables it wishes to handle by adding entries to
febug::FORMATTERS. If no handler was registered for a
type, or the lock was poisoned,
febug::debug_handler
()
will write a generic "not found" message. The key is
febug::Type, which can be constructed from
std::any::TypeId corresponding to the debugged type or
just an integer. The handler takes the write end of the pipe as the first
argument, and the variable ID as the second. It's a no-op if
febug::GLOBAL_CONTROLLED_SOCKET is
-1.
At any time, when the program wishes to expose a variable, it can
construct a febug::Wrapper (likely via one of the
convenience febug::StaticWrappable or
febug::Wrappable traits), which will send a
febug_message
with the specified type and signal
numbers (defaulting to SIGUSR2
), ID equal to the
address of the data argument, and name formatted. It's a no-op if
febug::GLOBAL_CONTROLLED_SOCKET is
-1.
When dropped, febug::Wrapper will send a
stop_febug_message
. It's a no-op if
febug::GLOBAL_CONTROLLED_SOCKET is
-1.
When it wishes to stop being debugged, the program
may call
febug::end
()
which will shut and reset
febug::GLOBAL_CONTROLLED_SOCKET. The program may omit
this if it'd be the last thing it did before exiting, since the kernel will
close all file descriptors and free all mappings anyway.
The following program spawns 10 threads, each successive one sorting a longer subsection of a String, but waits a quarter-second between each comparison; the String for each thread and the amount of comparisons can be inspected via a febug(8) mount:
// SPDX-License-Identifier: MIT extern crate febug; use std::sync::atomic::{AtomicUsize, Ordering}; use febug::{StaticWrappable, Wrapper}; use std::time::Duration; use std::any::TypeId; use std::io::Write; use std::fs::File; use std::thread; static COMPARISONS: AtomicUsize = AtomicUsize::new(0); fn main() { febug::start(); if febug::install_handler() { // Normal registration by TypeId, variables use .wrap(...) let mut fmt = febug::FORMATTERS.lock().unwrap(); fmt.insert(TypeId::of::<String>().into(), |of, vid| { let data = unsafe { &*(vid as *const String) }; let _ = of.write_all(data.as_bytes()); let _ = of.write_all(b"\n"); }); // Custom registration with an explicit type number and Wrapper::new() fmt.insert(0.into(), |of: &mut File, _| { let _ = write!(of, "{}\n", COMPARISONS.load(Ordering::Relaxed)); }); } let _comparisons_wrapper = Wrapper::new(0, &COMPARISONS, format_args!("comparisons")); let threads = (0..10) .map(|i| { thread::spawn(move || { let mut sorteing = "The quick red fox jumps over the lazy brown \ dog... tHE QUICK RED FOX JUMPS OVER THE \ LAZY BROWN DOG!!" [0..(i + 1) * 10] .to_string(); let _sorteing_w = sorteing.wrap(format_args!("cool_data_{}", i)); unsafe { sorteing.as_bytes_mut() }.sort_unstable_by(|a, b| { thread::sleep(Duration::from_millis(250)); COMPARISONS.fetch_add(1, Ordering::Relaxed); a.cmp(b) }); thread::sleep(Duration::from_secs(2)); }) }) .collect::<Vec<_>>(); for t in threads { let _ = t.join(); } }
febug-abi(5) —
the ABI wrapped by this library.
libfebug(3),
libfebug++(3), and
libfebug.py(3), —
equivalent C, C++, and Python libraries.
To all who support further development, in particular:
febug mailing list: <~nabijaczleweli/febug@lists.sr.ht>, archived at https://lists.sr.ht/~nabijaczleweli/febug
December 12, 2023 | febug 1.0.0-1-g3324bf81 |