serialize feedback

This commit is contained in:
Andrea Fioraldi 2020-12-16 13:19:16 +01:00
parent f7b9312f54
commit 06d5c82475
4 changed files with 34 additions and 43 deletions

View File

@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
//pub mod shmem_translated; //pub mod shmem_translated;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::{io::Write, time::Duration}; use std::time::Duration;
use crate::corpus::Corpus; use crate::corpus::Corpus;
use crate::executors::Executor; use crate::executors::Executor;
@ -60,7 +60,7 @@ impl ClientStats {
pub fn execs_per_sec(&self, cur_time: time::Duration) -> u64 { pub fn execs_per_sec(&self, cur_time: time::Duration) -> u64 {
if self.executions == 0 { if self.executions == 0 {
return 0; return 0;
} }
let secs = (cur_time - self.last_window_time).as_secs(); let secs = (cur_time - self.last_window_time).as_secs();
if secs == 0 { if secs == 0 {
self.last_execs_per_sec self.last_execs_per_sec

View File

@ -1,11 +1,12 @@
use alloc::vec::Vec; use alloc::vec::Vec;
use core::marker::PhantomData; use core::marker::PhantomData;
use num::Integer; use num::Integer;
use serde::{Deserialize, Serialize};
use crate::corpus::Testcase; use crate::corpus::Testcase;
use crate::inputs::Input; use crate::inputs::Input;
use crate::observers::{MapObserver, Observer, ObserversTuple}; use crate::observers::{MapObserver, Observer, ObserversTuple};
use crate::tuples::{MatchNameAndType, MatchType, Named, TupleList}; use crate::tuples::{Named, TupleList};
use crate::AflError; use crate::AflError;
pub type MaxMapFeedback<T, O> = MapFeedback<T, MaxReducer<T>, O>; pub type MaxMapFeedback<T, O> = MapFeedback<T, MaxReducer<T>, O>;
@ -17,7 +18,7 @@ pub type MinMapFeedback<T, O> = MapFeedback<T, MinReducer<T>, O>;
/// 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.
pub trait Feedback<I>: Named + 'static pub trait Feedback<I>: Named + serde::Serialize + serde::de::DeserializeOwned + 'static
where where
I: Input, I: Input,
{ {
@ -41,7 +42,7 @@ where
} }
} }
pub trait FeedbacksTuple<I>: MatchType + MatchNameAndType pub trait FeedbacksTuple<I>: serde::Serialize + serde::de::DeserializeOwned
where where
I: Input, I: Input,
{ {
@ -57,8 +58,6 @@ where
/// Discards metadata - the end of this input's execution /// Discards metadata - the end of this input's execution
fn discard_metadata_all(&mut self, input: &I) -> Result<(), AflError>; fn discard_metadata_all(&mut self, input: &I) -> Result<(), AflError>;
//fn for_each(&self, f: fn(&dyn Feedback<I>));
//fn for_each_mut(&mut self, f: fn(&mut dyn Feedback<I>));
} }
impl<I> FeedbacksTuple<I> for () impl<I> FeedbacksTuple<I> for ()
@ -78,8 +77,6 @@ where
fn discard_metadata_all(&mut self, _input: &I) -> Result<(), AflError> { fn discard_metadata_all(&mut self, _input: &I) -> Result<(), AflError> {
Ok(()) Ok(())
} }
//fn for_each(&self, f: fn(&dyn Feedback<I>)) {}
//fn for_each_mut(&mut self, f: fn(&mut dyn Feedback<I>)) {}
} }
impl<Head, Tail, I> FeedbacksTuple<I> for (Head, Tail) impl<Head, Tail, I> FeedbacksTuple<I> for (Head, Tail)
@ -106,36 +103,27 @@ where
self.0.discard_metadata(input)?; self.0.discard_metadata(input)?;
self.1.discard_metadata_all(input) self.1.discard_metadata_all(input)
} }
/*fn for_each(&self, f: fn(&dyn Feedback<I>)) {
f(&self.0);
self.1.for_each(f)
}
fn for_each_mut(&mut self, f: fn(&mut dyn Feedback<I>)) {
f(self.0);
self.1.for_each_mut(f)
}*/
} }
/// A Reducer function is used to aggregate values for the novelty search /// A Reducer function is used to aggregate values for the novelty search
pub trait Reducer<T>: 'static pub trait Reducer<T>: Serialize + serde::de::DeserializeOwned + 'static
where where
T: Integer + Copy + 'static, T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
fn reduce(first: T, second: T) -> T; fn reduce(first: T, second: T) -> T;
} }
#[derive(Serialize, Deserialize)]
pub struct MaxReducer<T> pub struct MaxReducer<T>
where where
T: Integer + Copy + 'static, T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
phantom: PhantomData<T>, phantom: PhantomData<T>,
} }
impl<T> Reducer<T> for MaxReducer<T> impl<T> Reducer<T> for MaxReducer<T>
where where
T: Integer + Copy + 'static, T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn reduce(first: T, second: T) -> T { fn reduce(first: T, second: T) -> T {
@ -147,16 +135,17 @@ where
} }
} }
#[derive(Serialize, Deserialize)]
pub struct MinReducer<T> pub struct MinReducer<T>
where where
T: Integer + Copy + 'static, T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
phantom: PhantomData<T>, phantom: PhantomData<T>,
} }
impl<T> Reducer<T> for MinReducer<T> impl<T> Reducer<T> for MinReducer<T>
where where
T: Integer + Copy + 'static, T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn reduce(first: T, second: T) -> T { fn reduce(first: T, second: T) -> T {
@ -169,25 +158,27 @@ where
} }
/// The most common AFL-like feedback type /// The most common AFL-like feedback type
#[derive(Serialize, Deserialize)]
#[serde(bound = "T: serde::de::DeserializeOwned")]
pub struct MapFeedback<T, R, O> pub struct MapFeedback<T, R, O>
where where
T: Integer + Default + Copy + 'static, T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
R: Reducer<T>, R: Reducer<T>,
O: MapObserver<T>, O: MapObserver<T>,
{ {
/// Contains information about untouched entries /// Contains information about untouched entries
history_map: Vec<T>, history_map: Vec<T>,
/// Name identifier of this instance /// Name identifier of this instance
name: &'static str, name: String,
/// Phantom Data of Reducer /// Phantom Data of Reducer
phantom: PhantomData<(R, O)>, phantom: PhantomData<(R, O)>,
} }
impl<T, R, O, I> Feedback<I> for MapFeedback<T, R, O> impl<T, R, O, I> Feedback<I> for MapFeedback<T, R, O>
where where
T: Integer + Default + Copy + 'static, T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
R: Reducer<T>, R: Reducer<T>,
O: MapObserver<T> + 'static, O: MapObserver<T>,
I: Input, I: Input,
{ {
fn is_interesting<OT: ObserversTuple>( fn is_interesting<OT: ObserversTuple>(
@ -215,19 +206,19 @@ where
impl<T, R, O> Named for MapFeedback<T, R, O> impl<T, R, O> Named for MapFeedback<T, R, O>
where where
T: Integer + Default + Copy + 'static, T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
R: Reducer<T>, R: Reducer<T>,
O: MapObserver<T> + 'static, O: MapObserver<T>,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &str {
self.name self.name.as_str()
} }
} }
impl<T, R, O> MapFeedback<T, R, O> impl<T, R, O> MapFeedback<T, R, O>
where where
T: Integer + Default + Copy + 'static, T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
R: Reducer<T>, R: Reducer<T>,
O: MapObserver<T> + Observer, O: MapObserver<T> + Observer,
{ {
@ -236,7 +227,7 @@ where
Self { Self {
history_map: vec![T::default(); map_size], history_map: vec![T::default(); map_size],
phantom: PhantomData, phantom: PhantomData,
name, name: name.to_string(),
} }
} }
@ -247,14 +238,14 @@ where
Self { Self {
history_map: vec![T::default(); map_observer.map().len()], history_map: vec![T::default(); map_observer.map().len()],
phantom: PhantomData, phantom: PhantomData,
name, name: name.to_string(),
} }
} }
} }
impl<T, R, O> MapFeedback<T, R, O> impl<T, R, O> MapFeedback<T, R, O>
where where
T: Integer + Default + Copy + 'static, T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
R: Reducer<T>, R: Reducer<T>,
O: MapObserver<T>, O: MapObserver<T>,
{ {

View File

@ -82,7 +82,7 @@ where
} }
/// A MapObserver observes the static map, as oftentimes used for afl-like coverage information /// A MapObserver observes the static map, as oftentimes used for afl-like coverage information
pub trait MapObserver<T> pub trait MapObserver<T>: Observer
where where
T: Default + Copy, T: Default + Copy,
{ {

View File

@ -98,15 +98,15 @@ pub trait Named {
} }
pub trait MatchNameAndType { pub trait MatchNameAndType {
fn match_name_type<T: 'static>(&self, name: &'static str) -> Option<&T>; fn match_name_type<T: 'static>(&self, name: &str) -> Option<&T>;
fn match_name_type_mut<T: 'static>(&mut self, name: &'static str) -> Option<&mut T>; fn match_name_type_mut<T: 'static>(&mut self, name: &str) -> Option<&mut T>;
} }
impl MatchNameAndType for () { impl MatchNameAndType for () {
fn match_name_type<T: 'static>(&self, _name: &'static str) -> Option<&T> { fn match_name_type<T: 'static>(&self, _name: &str) -> Option<&T> {
None None
} }
fn match_name_type_mut<T: 'static>(&mut self, _name: &'static str) -> Option<&mut T> { fn match_name_type_mut<T: 'static>(&mut self, _name: &str) -> Option<&mut T> {
None None
} }
} }
@ -116,7 +116,7 @@ where
Head: 'static + Named, Head: 'static + Named,
Tail: TupleList + MatchNameAndType, Tail: TupleList + MatchNameAndType,
{ {
fn match_name_type<T: 'static>(&self, name: &'static str) -> Option<&T> { fn match_name_type<T: 'static>(&self, name: &str) -> Option<&T> {
if TypeId::of::<T>() == TypeId::of::<Head>() && name == self.0.name() { if TypeId::of::<T>() == TypeId::of::<Head>() && name == self.0.name() {
unsafe { (&self.0 as *const _ as *const T).as_ref() } unsafe { (&self.0 as *const _ as *const T).as_ref() }
} else { } else {
@ -124,7 +124,7 @@ where
} }
} }
fn match_name_type_mut<T: 'static>(&mut self, name: &'static str) -> Option<&mut T> { fn match_name_type_mut<T: 'static>(&mut self, name: &str) -> Option<&mut T> {
if TypeId::of::<T>() == TypeId::of::<Head>() && name == self.0.name() { if TypeId::of::<T>() == TypeId::of::<Head>() && name == self.0.name() {
unsafe { (&mut self.0 as *mut _ as *mut T).as_mut() } unsafe { (&mut self.0 as *mut _ as *mut T).as_mut() }
} else { } else {