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

View File

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

View File

@ -98,15 +98,15 @@ pub trait Named {
}
pub trait MatchNameAndType {
fn match_name_type<T: 'static>(&self, name: &'static str) -> Option<&T>;
fn match_name_type_mut<T: 'static>(&mut self, name: &'static str) -> Option<&mut T>;
fn match_name_type<T: 'static>(&self, name: &str) -> Option<&T>;
fn match_name_type_mut<T: 'static>(&mut self, name: &str) -> Option<&mut T>;
}
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
}
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
}
}
@ -116,7 +116,7 @@ where
Head: 'static + Named,
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() {
unsafe { (&self.0 as *const _ as *const T).as_ref() }
} 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() {
unsafe { (&mut self.0 as *mut _ as *mut T).as_mut() }
} else {