benchmark with duration

This commit is contained in:
Alwin Berger 2023-01-09 12:39:51 +01:00
parent 9f97852e4a
commit 7ca2d43f3d
2 changed files with 55 additions and 13 deletions

View File

@ -1,7 +1,7 @@
//! A fuzzer using qemu in systemmode for binary-only coverage of kernels //! A fuzzer using qemu in systemmode for binary-only coverage of kernels
//! //!
use core::time::Duration; use core::time::Duration;
use std::{env, path::PathBuf, process, io::Read, fs}; use std::{env, path::PathBuf, process, io::{Read, Write}, fs::{self, OpenOptions}};
use libafl::{ use libafl::{
bolts::{ bolts::{
@ -315,19 +315,19 @@ pub fn fuzz() {
println!("Iterations {}",t); println!("Iterations {}",t);
let num = str::parse::<u64>(&t).expect("FUZZ_ITERS was not a number"); let num = str::parse::<u64>(&t).expect("FUZZ_ITERS was not a number");
fuzzer fuzzer
.fuzz_loop_for(&mut stages, &mut executor, &mut state, &mut mgr, num) .fuzz_loop_for_duration(&mut stages, &mut executor, &mut state, &mut mgr, Duration::from_secs(num))
.unwrap(); .unwrap();
let mut strbuf = String::new(); if let Ok(td) = env::var("TIME_DUMP") {
let mut file = OpenOptions::new()
unsafe { .read(true)
for i in ICOUNT_HISTORY.iter() { .write(true)
strbuf.push_str(&format!("{}\n",i)); .create(true)
} .append(false)
} .open(td).expect("Could not open timedump");
match env::var("TIME_DUMP") { unsafe {
Err(_) => (), for i in ICOUNT_HISTORY.iter() {
Ok(td) => { writeln!(file, "{}", i).expect("Write to dump failed");
fs::write(td, strbuf).expect("could not write time dump"); }
} }
} }
}, },

View File

@ -229,6 +229,48 @@ where
Ok(ret) Ok(ret)
} }
/// Fuzz for n iterations.
/// Returns the index of the last fuzzed corpus item.
/// (Note: An iteration represents a complete run of every stage.
/// therefore the number n is not always equal to the number of the actual harness executions,
/// because each stage could run the harness for multiple times)
///
/// If you use this fn in a restarting scenario to only run for `n` iterations,
/// before exiting, make sure you call `event_mgr.on_restart(&mut state)?;`.
/// This way, the state will be available in the next, respawned, iteration.
fn fuzz_loop_for_duration(
&mut self,
stages: &mut ST,
executor: &mut E,
state: &mut EM::State,
manager: &mut EM,
time: Duration
) -> Result<usize, Error> {
if time==Duration::ZERO {
return Err(Error::illegal_argument(
"Cannot fuzz for 0 duration!".to_string(),
));
}
let mut ret = 0;
let mut last = current_time();
let monitor_timeout = STATS_TIMEOUT_DEFAULT;
let starttime = std::time::Instant::now();
while std::time::Instant::now().duration_since(starttime) < time {
ret = self.fuzz_one(stages, executor, state, manager)?;
last = manager.maybe_report_progress(state, last, monitor_timeout)?;
}
// If we would assume the fuzzer loop will always exit after this, we could do this here:
// manager.on_restart(state)?;
// But as the state may grow to a few megabytes,
// for now we won' and the user has to do it (unless we find a way to do this on `Drop`).
Ok(ret)
}
} }
/// The corpus this input should be added to /// The corpus this input should be added to