Always show user monitor in SimpleMonitor (#3202)

* *recursion* is not proper

* user monitor on

* api changer

* no submodule anymore
This commit is contained in:
Dongjia "toka" Zhang 2025-05-07 18:17:58 +02:00 committed by GitHub
parent f33376f1cd
commit d8f8640982
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 37 additions and 60 deletions

View File

@ -203,7 +203,7 @@ pub fn main() {
// The Monitor trait define how the fuzzer stats are displayed to the user // The Monitor trait define how the fuzzer stats are displayed to the user
#[cfg(not(feature = "tui"))] #[cfg(not(feature = "tui"))]
let mon = SimpleMonitor::with_user_monitor(|s| println!("{s}")); let mon = SimpleMonitor::new(|s| println!("{s}"));
#[cfg(feature = "tui")] #[cfg(feature = "tui")]
let mon = TuiMonitor::builder() let mon = TuiMonitor::builder()
.title("Baby Fuzzer") .title("Baby Fuzzer")

View File

@ -232,7 +232,7 @@ fn fuzz(
let file_null = File::open("/dev/null")?; let file_null = File::open("/dev/null")?;
// 'While the stats are state, they are usually used in the broker - which is likely never restarted // 'While the stats are state, they are usually used in the broker - which is likely never restarted
let monitor = SimpleMonitor::with_user_monitor(|s| { let monitor = SimpleMonitor::new(|s| {
#[cfg(unix)] #[cfg(unix)]
writeln!(&mut stdout_cpy, "{s}").unwrap(); writeln!(&mut stdout_cpy, "{s}").unwrap();
#[cfg(windows)] #[cfg(windows)]

View File

@ -180,7 +180,7 @@ pub fn fuzz() -> Result<(), Error> {
let stack_ptr: GuestAddr = qemu.read_reg(Regs::Sp).unwrap(); let stack_ptr: GuestAddr = qemu.read_reg(Regs::Sp).unwrap();
let monitor = SimpleMonitor::with_user_monitor(|s| { let monitor = SimpleMonitor::new(|s| {
println!("{s}"); println!("{s}");
}); });
let (state, mut mgr) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider) let (state, mut mgr) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider)

View File

@ -223,7 +223,7 @@ pub fn fuzz() -> Result<(), Error> {
}; };
// Set up the most basic monitor possible. // Set up the most basic monitor possible.
let monitor = SimpleMonitor::with_user_monitor(|s| { let monitor = SimpleMonitor::new(|s| {
println!("{s}"); println!("{s}");
}); });
let (state, mut mgr) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider) let (state, mut mgr) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider)

View File

@ -149,7 +149,7 @@ pub fn main() {
.unwrap(); .unwrap();
// The Monitor trait define how the fuzzer stats are reported to the user // The Monitor trait define how the fuzzer stats are reported to the user
let monitor = SimpleMonitor::with_user_monitor(|s| { let monitor = SimpleMonitor::new(|s| {
println!("{s}"); println!("{s}");
}); });

View File

@ -153,7 +153,6 @@ where
F: FnMut(&str), F: FnMut(&str),
{ {
print_fn: F, print_fn: F,
print_user_monitor: bool,
} }
impl<F> Debug for SimpleMonitor<F> impl<F> Debug for SimpleMonitor<F>
@ -188,12 +187,10 @@ where
global_stats.execs_per_sec_pretty global_stats.execs_per_sec_pretty
); );
if self.print_user_monitor { client_stats_manager.client_stats_insert(sender_id)?;
client_stats_manager.client_stats_insert(sender_id)?; let client = client_stats_manager.client_stats_for(sender_id)?;
let client = client_stats_manager.client_stats_for(sender_id)?; for (key, val) in client.user_stats() {
for (key, val) in client.user_stats() { write!(fmt, ", {key}: {val}").unwrap();
write!(fmt, ", {key}: {val}").unwrap();
}
} }
(self.print_fn)(&fmt); (self.print_fn)(&fmt);
@ -222,10 +219,7 @@ where
{ {
/// Creates the monitor, using the `current_time` as `start_time`. /// Creates the monitor, using the `current_time` as `start_time`.
pub fn new(print_fn: F) -> Self { pub fn new(print_fn: F) -> Self {
Self { Self { print_fn }
print_fn,
print_user_monitor: false,
}
} }
/// Creates the monitor with a given `start_time`. /// Creates the monitor with a given `start_time`.
@ -236,14 +230,6 @@ where
pub fn with_time(print_fn: F, _start_time: Duration) -> Self { pub fn with_time(print_fn: F, _start_time: Duration) -> Self {
Self::new(print_fn) Self::new(print_fn)
} }
/// Creates the monitor that also prints the user monitor
pub fn with_user_monitor(print_fn: F) -> Self {
Self {
print_fn,
print_user_monitor: true,
}
}
} }
/// Start the timer /// Start the timer

View File

@ -246,14 +246,14 @@ fn main() {
let target_family = std::env::var("CARGO_CFG_TARGET_FAMILY").unwrap(); let target_family = std::env::var("CARGO_CFG_TARGET_FAMILY").unwrap();
if target_family == "windows" { if target_family == "windows" {
println!("cargo:rerun-if-changed=src/windows_asan.c"); println!("cargo:rerun-if-changed=src/windows_asan.c");
let mut windows_asan = cc::Build::new(); let mut windows_asan = cc::Build::new();
#[cfg(feature = "whole_archive")] #[cfg(feature = "whole_archive")]
{ {
windows_asan.link_lib_modifier("+whole-archive"); windows_asan.link_lib_modifier("+whole-archive");
} }
windows_asan windows_asan
.file(src_dir.join("windows_asan.c")) .file(src_dir.join("windows_asan.c"))
.compile("windows_asan"); .compile("windows_asan");

View File

@ -1,12 +1,11 @@
//! Forkserver logic into targets //! Forkserver logic into targets
use core::sync::atomic::{AtomicBool, Ordering};
use std::{ use std::{
os::fd::{AsFd, AsRawFd, BorrowedFd}, os::fd::{AsFd, AsRawFd, BorrowedFd},
sync::OnceLock, sync::OnceLock,
}; };
use core::sync::atomic::{AtomicBool, Ordering};
use libafl::{ use libafl::{
Error, Error,
executors::forkserver::{ executors::forkserver::{
@ -15,7 +14,6 @@ use libafl::{
}, },
}; };
use libafl_bolts::os::{ChildHandle, ForkResult}; use libafl_bolts::os::{ChildHandle, ForkResult};
use nix::{ use nix::{
sys::signal::{SigHandler, Signal}, sys::signal::{SigHandler, Signal},
unistd::Pid, unistd::Pid,
@ -293,11 +291,8 @@ impl ForkserverParent for MaybePersistentForkserverParent {
// a child, wait it, and get a stopped signal. Moreover, was_killed is // a child, wait it, and get a stopped signal. Moreover, was_killed is
// true only if the forkserver killed such child. In all cases, the // true only if the forkserver killed such child. In all cases, the
// last_child_pid will never be None. // last_child_pid will never be None.
if nix::sys::wait::waitpid( if nix::sys::wait::waitpid(Pid::from_raw(self.last_child_pid.take().unwrap()), None)
Pid::from_raw(self.last_child_pid.take().unwrap()), .is_err()
None,
)
.is_err()
{ {
return Err(Error::illegal_state("child_stopped && was_killed")); return Err(Error::illegal_state("child_stopped && was_killed"));
} }
@ -306,7 +301,7 @@ impl ForkserverParent for MaybePersistentForkserverParent {
if self.child_stopped { if self.child_stopped {
// Special handling for persistent mode: if the child is alive but // Special handling for persistent mode: if the child is alive but
// currently stopped, simply restart it with SIGCONT. // currently stopped, simply restart it with SIGCONT.
// unwrap here: child_stopped is true only if last_child_pid is some. // unwrap here: child_stopped is true only if last_child_pid is some.
let child_pid = *self.last_child_pid.as_ref().unwrap(); let child_pid = *self.last_child_pid.as_ref().unwrap();
nix::sys::signal::kill(Pid::from_raw(child_pid), Signal::SIGCONT)?; nix::sys::signal::kill(Pid::from_raw(child_pid), Signal::SIGCONT)?;
@ -323,15 +318,21 @@ impl ForkserverParent for MaybePersistentForkserverParent {
} }
ForkResult::Child => unsafe { ForkResult::Child => unsafe {
// unwrap here: the field is assigned in `pre_fuzzing` // unwrap here: the field is assigned in `pre_fuzzing`
nix::sys::signal::signal(Signal::SIGCHLD, self.old_sigchld_handler.take().unwrap()) nix::sys::signal::signal(
.inspect_err(|_| { Signal::SIGCHLD,
log::error!("Fail to restore signal handler for SIGCHLD."); self.old_sigchld_handler.take().unwrap(),
})?; )
.inspect_err(|_| {
log::error!("Fail to restore signal handler for SIGCHLD.");
})?;
// unwrap here: the field is assigned in `pre_fuzzing` // unwrap here: the field is assigned in `pre_fuzzing`
nix::sys::signal::signal(Signal::SIGTERM, self.old_sigterm_handler.take().unwrap()) nix::sys::signal::signal(
.inspect_err(|_| { Signal::SIGTERM,
log::error!("Fail to restore signal handler for SIGTERM."); self.old_sigterm_handler.take().unwrap(),
})?; )
.inspect_err(|_| {
log::error!("Fail to restore signal handler for SIGTERM.");
})?;
}, },
} }
Ok(fork_result) Ok(fork_result)
@ -341,7 +342,8 @@ impl ForkserverParent for MaybePersistentForkserverParent {
fn handle_child_requests(&mut self) -> Result<i32, Error> { fn handle_child_requests(&mut self) -> Result<i32, Error> {
let mut status = 0i32; let mut status = 0i32;
// unwrap here: the field is assigned if we are parent process in `spawn_child` // unwrap here: the field is assigned if we are parent process in `spawn_child`
if unsafe { libc::waitpid(*self.last_child_pid.as_ref().unwrap(), &raw mut status, 0) < 0 } { if unsafe { libc::waitpid(*self.last_child_pid.as_ref().unwrap(), &raw mut status, 0) < 0 }
{
return Err(Error::illegal_state("waitpid")); return Err(Error::illegal_state("waitpid"));
} }
if libc::WIFSTOPPED(status) { if libc::WIFSTOPPED(status) {

View File

@ -75,4 +75,4 @@ eval "$CLIPPY_CMD --workspace -- $RUSTC_FLAGS"
echo "Clippy run completed for all specified projects." echo "Clippy run completed for all specified projects."
# Last run it on all # Last run it on all
eval "$CLIPPY_CMD --workspace -- $RUSTC_FLAGS" eval "$CLIPPY_CMD --workspace -- $RUSTC_FLAGS"

View File

@ -5,22 +5,11 @@ cd "$SCRIPT_DIR/.." || exit 1
# TODO: This should be rewritten in rust, a Makefile, or some platform-independent language # TODO: This should be rewritten in rust, a Makefile, or some platform-independent language
if [[ -z "${RUN_ON_CI}" ]]; then fuzzer_to_test="$1"
fuzzers=$(find ./fuzzers -mindepth 1 -maxdepth 1 -type d) export PROFILE=dev
backtrace_fuzzers=$(find ./fuzzers/backtrace_baby_fuzzers -mindepth 1 -maxdepth 1 -type d) export PROFILE_DIR=debug
fuzzer_to_test="$fuzzers $backtrace_fuzzers"
else
fuzzer_to_test="$1"
export PROFILE=dev
export PROFILE_DIR=debug
fi
echo "Testing" "$fuzzer_to_test" echo "Testing" "$fuzzer_to_test"
# build with a shared target dir for all fuzzers. this should speed up
# compilation a bit, and allows for easier artifact management (caching and
# cargo clean).
git submodule init && git submodule update
# override default profile settings for speed # override default profile settings for speed
# export RUSTFLAGS="-C prefer-dynamic" # export RUSTFLAGS="-C prefer-dynamic"