introduce ShadowTracingStage

This commit is contained in:
Andrea Fioraldi 2021-06-09 14:17:43 +02:00
parent 9e9425c622
commit 2b16e92461
2 changed files with 88 additions and 5 deletions

View File

@ -1,4 +1,4 @@
//! A `ShadowExecutor` wraps an executor to have shadow observer that will not be considered by the manager //! A `ShadowExecutor` wraps an executor to have shadow observer that will not be considered by the feedbacks and the manager
use crate::{ use crate::{
executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks}, executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
@ -27,7 +27,7 @@ pub trait HasShadowObserverHooks<EM, I, S, SOT, Z> {
) -> Result<(), Error>; ) -> Result<(), Error>;
} }
/// A [`ShadowExecutor`] wraps a primary executor, forwarding its methods, and a secondary one /// A [`ShadowExecutor`] wraps an executor and a set of shadow observers
pub struct ShadowExecutor<E, SOT> { pub struct ShadowExecutor<E, SOT> {
executor: E, executor: E,
shadow_observers: SOT, shadow_observers: SOT,
@ -70,6 +70,14 @@ where
pub fn shadow_observers_mut(&mut self) -> &mut SOT { pub fn shadow_observers_mut(&mut self) -> &mut SOT {
&mut self.shadow_observers &mut self.shadow_observers
} }
pub fn shadow_hooks(&self) -> &bool {
&self.shadow_hooks
}
pub fn shadow_hooks_mut(&mut self) -> &mut bool {
&mut self.shadow_hooks
}
} }
impl<E, EM, I, S, SOT, Z> HasShadowObserverHooks<EM, I, S, SOT, Z> for ShadowExecutor<E, SOT> impl<E, EM, I, S, SOT, Z> HasShadowObserverHooks<EM, I, S, SOT, Z> for ShadowExecutor<E, SOT>

View File

@ -2,7 +2,7 @@ use core::{marker::PhantomData, mem::drop};
use crate::{ use crate::{
corpus::Corpus, corpus::Corpus,
executors::{Executor, HasExecHooksTuple, HasObservers, HasObserversHooks}, executors::{Executor, HasExecHooksTuple, HasObservers, HasObserversHooks, ShadowExecutor},
inputs::Input, inputs::Input,
mark_feature_time, mark_feature_time,
observers::ObserversTuple, observers::ObserversTuple,
@ -15,7 +15,7 @@ use crate::{
#[cfg(feature = "introspection")] #[cfg(feature = "introspection")]
use crate::stats::PerfFeature; use crate::stats::PerfFeature;
/// The default mutational stage /// A stage that runs a tracer executor
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct TracingStage<C, EM, I, OT, S, TE, Z> pub struct TracingStage<C, EM, I, OT, S, TE, Z>
where where
@ -87,7 +87,7 @@ where
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>, OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>, S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>,
{ {
/// Creates a new default mutational stage /// Creates a new default stage
pub fn new(tracer_executor: TE) -> Self { pub fn new(tracer_executor: TE) -> Self {
Self { Self {
tracer_executor, tracer_executor,
@ -95,3 +95,78 @@ where
} }
} }
} }
/// A stage that runs the shadow executor using also the shadow observers
#[derive(Clone, Debug)]
pub struct ShadowTracingStage<C, E, EM, I, OT, S, SOT, Z> {
#[allow(clippy::type_complexity)]
phantom: PhantomData<(C, E, EM, I, OT, S, SOT, Z)>,
}
impl<C, E, EM, I, OT, S, SOT, Z> Stage<ShadowExecutor<E, SOT>, EM, S, Z>
for ShadowTracingStage<C, E, EM, I, OT, S, SOT, Z>
where
I: Input,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Z>,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
SOT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>,
{
#[inline]
fn perform(
&mut self,
fuzzer: &mut Z,
executor: &mut ShadowExecutor<E, SOT>,
state: &mut S,
manager: &mut EM,
corpus_idx: usize,
) -> Result<(), Error> {
start_timer!(state);
let input = state
.corpus()
.get(corpus_idx)?
.borrow_mut()
.load_input()?
.clone();
mark_feature_time!(state, PerfFeature::GetInputFromCorpus);
let prev_shadow_hooks = *executor.shadow_hooks();
*executor.shadow_hooks_mut() = true;
start_timer!(state);
executor.pre_exec_observers(fuzzer, state, manager, &input)?;
mark_feature_time!(state, PerfFeature::PreExecObservers);
start_timer!(state);
drop(executor.run_target(fuzzer, state, manager, &input)?);
mark_feature_time!(state, PerfFeature::TargetExecution);
*state.executions_mut() += 1;
start_timer!(state);
executor.post_exec_observers(fuzzer, state, manager, &input)?;
mark_feature_time!(state, PerfFeature::PostExecObservers);
*executor.shadow_hooks_mut() = prev_shadow_hooks;
Ok(())
}
}
impl<C, E, EM, I, OT, S, SOT, Z> ShadowTracingStage<C, E, EM, I, OT, S, SOT, Z>
where
I: Input,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Z>,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
SOT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>,
{
/// Creates a new default stage
pub fn new(_executor: &mut ShadowExecutor<E, SOT>) -> Self {
Self {
phantom: PhantomData,
}
}
}