LIBFEBUG.RS(3) | Library Functions Manual | LIBFEBUG.RS(3) |
febug::start()
, febug::Wrapper
,
febug::Wrappable
,
febug::StaticWrappable
,
febug::GLOBAL_CONTROLLED_SOCKET
,
febug::FORMATTERS
—
[dependencies] febug = "0.2.1"
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
();
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;
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
std::any::TypeId corresponding to the debugged type;
if your type is not 'static, lie here. 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.
// SPDX-License-Identifier: MIT extern crate febug; use febug::StaticWrappable; use std::time::Duration; use std::any::TypeId; use std::io::Write; use std::thread; fn main() { febug::start(); if febug::install_handler() { febug::FORMATTERS.lock() .unwrap() .insert(TypeId::of::<String>(), |of, vid| { let data = unsafe { &*(vid as *const String) }; let _ = of.write_all(data.as_bytes()); let _ = of.write_all(b"\n"); }); } 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)); a.cmp(b) }); thread::sleep(Duration::from_secs(2)); }) }) .collect::<Vec<_>>(); for t in threads { let _ = t.join(); } }
febug mailing list: <~nabijaczleweli/febug@lists.sr.ht>, archived at https://lists.sr.ht/~nabijaczleweli/febug
June 12, 2023 | febug 0.2.1 |