TimeFeedback

This commit is contained in:
Andrea Fioraldi 2021-03-09 15:12:48 +01:00
parent 6709c966d5
commit 87cad475e3
2 changed files with 65 additions and 3 deletions

View File

@ -11,10 +11,12 @@ use crate::{
corpus::Testcase, corpus::Testcase,
executors::ExitKind, executors::ExitKind,
inputs::Input, inputs::Input,
observers::ObserversTuple, observers::{ObserversTuple, TimeObserver},
Error, Error,
}; };
use core::time::Duration;
/// Feedbacks evaluate the observers. /// Feedbacks evaluate the observers.
/// Basically, they reduce the information provided by an observer to a value, /// Basically, they reduce the information provided by an observer to a value,
/// indicating the "interestingness" of the last run. /// indicating the "interestingness" of the last run.
@ -154,3 +156,59 @@ impl Default for CrashFeedback {
Self::new() Self::new()
} }
} }
/// Nop feedback that annotates execution time in the new testcase, if any
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct TimeFeedback {
exec_time: Option<Duration>,
}
impl<I> Feedback<I> for TimeFeedback
where
I: Input,
{
fn is_interesting<OT: ObserversTuple>(
&mut self,
_input: &I,
observers: &OT,
_exit_kind: ExitKind,
) -> Result<u32, Error> {
let observer = observers.match_first_type::<TimeObserver>().unwrap();
self.exec_time = *observer.last_runtime();
Ok(0)
}
/// Append to the testcase the generated metadata in case of a new corpus item
#[inline]
fn append_metadata(&mut self, testcase: &mut Testcase<I>) -> Result<(), Error> {
*testcase.exec_time_mut() = self.exec_time;
self.exec_time = None;
Ok(())
}
/// Discard the stored metadata in case that the testcase is not added to the corpus
#[inline]
fn discard_metadata(&mut self, _input: &I) -> Result<(), Error> {
self.exec_time = None;
Ok(())
}
}
impl Named for TimeFeedback {
#[inline]
fn name(&self) -> &str {
"TimeFeedback"
}
}
impl TimeFeedback {
pub fn new() -> Self {
Self { exec_time: None }
}
}
impl Default for TimeFeedback {
fn default() -> Self {
Self::new()
}
}

View File

@ -9,7 +9,7 @@ use core::time::Duration;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
bolts::tuples::{MatchNameAndType, MatchType, Named, TupleList}, bolts::tuples::{MatchFirstType, MatchNameAndType, MatchType, Named, TupleList},
utils::current_time, utils::current_time,
Error, Error,
}; };
@ -52,7 +52,7 @@ pub trait Observer: Named + serde::Serialize + serde::de::DeserializeOwned + 'st
/// A hastkel-style tuple of observers /// A hastkel-style tuple of observers
pub trait ObserversTuple: pub trait ObserversTuple:
MatchNameAndType + MatchType + serde::Serialize + serde::de::DeserializeOwned MatchNameAndType + MatchType + MatchFirstType + serde::Serialize + serde::de::DeserializeOwned
{ {
/// Reset all executors in the tuple /// Reset all executors in the tuple
/// This is called right before the next execution. /// This is called right before the next execution.
@ -105,6 +105,10 @@ impl TimeObserver {
last_runtime: None, last_runtime: None,
} }
} }
pub fn last_runtime(&self) -> &Option<Duration> {
&self.last_runtime
}
} }
impl Observer for TimeObserver { impl Observer for TimeObserver {