Aarnav eff40320eb
Add Stoppable trait to State which exposes an API to stop the fuzzer (#2325)
* add HasStopNext to State which exposes an API to stop the fuzzer. Stops the fuzzer in fuzz_loop or
fuzz_loop_for when set to true

* fix import

* rename HasStopNext to HasShouldStopFuzzing and stop_next to should_stop_fuzzing

* added HasShouldStopFuzzing trait constraint for libafl_libfuzzer_runtime fuzzer

* rename HasShouldStopFuzzing to Stoppable and add it as a type constraint in libafl_libfuzzer report.rs

* rename should_stop_fuzzing -> should_stop

* introduce Event::Stop

* fix prelude import

* Call send_exiting when processing Event::Stop in restartable managers

* fix clippy

* introduce on_shutdown function in EventProcessor, a function to exit
without saving state gracefully. In contrast with on_restart.

* call manager.on_shutdown when stopping in fuzz_loop due to state.should_stop

* Add missing on_shutdown implementations
Check after every stage in Stages::perform_all if should exit and do so.

* remove specialization

* fix doc

* introduce EventProcessor constraint in libafl_libfuzzer_runtime
run clippy in libafl_libfuzzer_runtime

* fix CentralizedEventManager's on_shutdown not calling inner.on_shutdown

* fix bugs in CentralizedLauncher that wouldn't allow children to terminate properly

* don't call send_exiting when processing Event::Stop since it will be called when calling on_shutdown anyways

* clippy

* add set_exit_after so broker does not need to inner_mut to set exit_cleanly_after

* return Cow<str> from Event::name_detailed instead of a String

* fix missing import in libafl_libfuzzer_runtime

* add initate_stop and reset_stop to Stoppable trait to superceed should_stop_mut

* clippy

* typo

* rename initate_stop to request_stop, should_stop to stop_requested and reset_stop to discard_stop_request

* fix missing import

* windows clippy fix

* fix broker typo
2024-07-02 17:45:20 +02:00

61 lines
1.7 KiB
Rust

use std::ffi::c_int;
use libafl::{
events::{EventProcessor, ProgressReporter, SimpleEventManager},
executors::HasObservers,
feedbacks::MapFeedbackMetadata,
inputs::UsesInput,
monitors::SimpleMonitor,
stages::{HasCurrentStage, StagesTuple},
state::{HasExecutions, HasLastReportTime, Stoppable},
Error, Fuzzer, HasMetadata, HasNamedMetadata,
};
use crate::{fuzz_with, options::LibfuzzerOptions};
#[allow(clippy::unnecessary_wraps, clippy::cast_precision_loss)]
fn do_report<F, ST, E, S, EM>(
_options: &LibfuzzerOptions,
_fuzzer: &mut F,
_stages: &mut ST,
_executor: &mut E,
state: &S,
_mgr: &mut EM,
) -> Result<(), Error>
where
F: Fuzzer<E, EM, ST, State = S>,
S: HasMetadata
+ HasNamedMetadata
+ HasExecutions
+ UsesInput
+ HasLastReportTime
+ HasCurrentStage
+ Stoppable,
E: HasObservers<State = S>,
EM: ProgressReporter<State = S> + EventProcessor<E, F>,
ST: StagesTuple<E, EM, S, F>,
{
let meta = state
.named_metadata::<MapFeedbackMetadata<u8>>("edges")
.unwrap();
let observed = meta.history_map.iter().filter(|&&e| e != 0).count();
let total = meta.history_map.len();
println!(
"Observed {observed}/{total} edges ({}%)",
observed as f64 / total as f64
);
Ok(())
}
pub fn report(
options: &LibfuzzerOptions,
harness: &extern "C" fn(*const u8, usize) -> c_int,
) -> Result<(), Error> {
fuzz_with!(options, harness, do_report, |reporter| {
let mgr = SimpleEventManager::new(SimpleMonitor::new(|s| eprintln!("{s}")));
crate::start_fuzzing_single(reporter, None, mgr)
})
}