Remove executor hooks (#124)

* remove HasExecHooks from Executor

* adapt the frida executor

* adapt frida and avoid recursive type infearence

* fix win build
This commit is contained in:
Andrea Fioraldi 2021-05-25 15:19:10 +02:00 committed by GitHub
parent 7493b59ba8
commit 46716e8090
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 143 additions and 349 deletions

View File

@ -20,7 +20,7 @@ use libafl::{
QueueCorpusScheduler,
},
executors::{
inprocess::InProcessExecutor, timeout::TimeoutExecutor, Executor, ExitKind, HasExecHooks,
inprocess::InProcessExecutor, timeout::TimeoutExecutor, Executor, ExitKind,
HasExecHooksTuple, HasObservers, HasObserversHooks,
},
feedback_or,
@ -65,7 +65,7 @@ where
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
base: TimeoutExecutor<InProcessExecutor<'a, H, I, OT, S>, I>,
base: TimeoutExecutor<InProcessExecutor<'a, H, I, OT, S>>,
/// Frida's dynamic rewriting engine
stalker: Stalker<'a>,
/// User provided callback for instrumentation
@ -74,7 +74,7 @@ where
_phantom: PhantomData<&'b u8>,
}
impl<'a, 'b, 'c, FH, H, I, OT, S> Executor<I>
impl<'a, 'b, 'c, EM, FH, H, I, OT, S, Z> Executor<EM, I, S, Z>
for FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S>
where
FH: FridaHelper<'b>,
@ -84,7 +84,14 @@ where
{
/// Instruct the target about the input and run
#[inline]
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> {
fn run_target(
&mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<ExitKind, Error> {
self.helper.pre_exec(input);
if self.helper.stalker_enabled() {
if self.followed {
self.stalker.activate(NativePointer(
@ -96,7 +103,7 @@ where
.follow_me::<NoneEventSink>(self.helper.transformer(), None);
}
}
let res = self.base.run_target(input);
let res = self.base.run_target(fuzzer, state, mgr, input);
if self.helper.stalker_enabled() {
self.stalker.deactivate();
}
@ -109,42 +116,8 @@ where
if self.helper.stalker_enabled() {
self.stalker.deactivate();
}
res
}
}
impl<'a, 'b, 'c, EM, FH, H, I, OT, S, Z> HasExecHooks<EM, I, S, Z>
for FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S>
where
FH: FridaHelper<'b>,
H: FnMut(&I) -> ExitKind,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
/// Called right before exexution starts
#[inline]
fn pre_exec(
&mut self,
fuzzer: &mut Z,
state: &mut S,
event_mgr: &mut EM,
input: &I,
) -> Result<(), Error> {
self.helper.pre_exec(input);
self.base.pre_exec(fuzzer, state, event_mgr, input)
}
/// Called right after execution finished.
#[inline]
fn post_exec(
&mut self,
fuzzer: &mut Z,
state: &mut S,
event_mgr: &mut EM,
input: &I,
) -> Result<(), Error> {
self.helper.post_exec(input);
self.base.post_exec(fuzzer, state, event_mgr, input)
res
}
}

View File

@ -328,6 +328,7 @@ where
event: Event<I>,
) -> Result<(), Error>
where
E: Executor<Self, I, S, Z>,
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>,
{
match event {
@ -346,6 +347,7 @@ where
let observers: OT = postcard::from_bytes(&observers_buf)?;
// TODO include ExitKind in NewTestcase
// TODO check for objective too
let is_interesting =
fuzzer.is_interesting(state, self, &input, &observers, &ExitKind::Ok)?;
if fuzzer
@ -423,7 +425,7 @@ impl<E, I, OT, S, SP, ST, Z> EventProcessor<E, S, Z> for LlmpEventManager<I, OT,
where
SP: ShMemProvider,
ST: Stats,
E: Executor<I>,
E: Executor<Self, I, S, Z>,
I: Input,
OT: ObserversTuple,
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>, //CE: CustomEvent<I>,
@ -469,7 +471,7 @@ impl<E, I, OT, S, SP, ST, Z> EventManager<E, I, S, Z> for LlmpEventManager<I, OT
where
SP: ShMemProvider,
ST: Stats,
E: Executor<I>,
E: Executor<Self, I, S, Z>,
I: Input,
OT: ObserversTuple,
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>, //CE: CustomEvent<I>,
@ -573,7 +575,7 @@ where
impl<E, I, OT, S, SP, ST, Z> EventProcessor<E, S, Z>
for LlmpRestartingEventManager<I, OT, S, SP, ST>
where
E: Executor<I>,
E: Executor<LlmpEventManager<I, OT, S, SP, ST>, I, S, Z>,
I: Input,
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>,
OT: ObserversTuple,
@ -589,7 +591,7 @@ where
impl<E, I, OT, S, SP, ST, Z> EventManager<E, I, S, Z>
for LlmpRestartingEventManager<I, OT, S, SP, ST>
where
E: Executor<I>,
E: Executor<LlmpEventManager<I, OT, S, SP, ST>, I, S, Z>,
I: Input,
S: Serialize,
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>,

View File

@ -1,41 +1,22 @@
//! A `CombinedExecutor` wraps a primary executor and a secondary one
use core::marker::PhantomData;
use crate::{
executors::{
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
},
executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
inputs::Input,
observers::ObserversTuple,
Error,
};
/// A [`CombinedExecutor`] wraps a primary executor, forwarding its methods, and a secondary one
pub struct CombinedExecutor<A, B, I>
where
A: Executor<I>,
B: Executor<I>,
I: Input,
{
pub struct CombinedExecutor<A, B> {
primary: A,
secondary: B,
phantom: PhantomData<I>,
}
impl<A, B, I> CombinedExecutor<A, B, I>
where
A: Executor<I>,
B: Executor<I>,
I: Input,
{
impl<A, B> CombinedExecutor<A, B> {
/// Create a new `CombinedExecutor`, wrapping the given `executor`s.
pub fn new(primary: A, secondary: B) -> Self {
Self {
primary,
secondary,
phantom: PhantomData,
}
pub fn new<EM, I, S, Z>(primary: A, secondary: B) -> Self {
Self { primary, secondary }
}
/// Retrieve the primary `Executor` that is wrapped by this `CombinedExecutor`.
@ -49,22 +30,26 @@ where
}
}
impl<A, B, I> Executor<I> for CombinedExecutor<A, B, I>
impl<A, B, EM, I, S, Z> Executor<EM, I, S, Z> for CombinedExecutor<A, B>
where
A: Executor<I>,
B: Executor<I>,
A: Executor<EM, I, S, Z>,
B: Executor<EM, I, S, Z>,
I: Input,
{
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> {
self.primary.run_target(input)
fn run_target(
&mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<ExitKind, Error> {
self.primary.run_target(fuzzer, state, mgr, input)
}
}
impl<A, B, I, OT> HasObservers<OT> for CombinedExecutor<A, B, I>
impl<A, B, OT> HasObservers<OT> for CombinedExecutor<A, B>
where
A: Executor<I> + HasObservers<OT>,
B: Executor<I>,
I: Input,
A: HasObservers<OT>,
OT: ObserversTuple,
{
#[inline]
@ -78,40 +63,10 @@ where
}
}
impl<A, B, EM, I, OT, S, Z> HasObserversHooks<EM, I, OT, S, Z> for CombinedExecutor<A, B, I>
impl<A, B, EM, I, OT, S, Z> HasObserversHooks<EM, I, OT, S, Z> for CombinedExecutor<A, B>
where
A: Executor<I> + HasObservers<OT>,
B: Executor<I>,
A: HasObservers<OT>,
I: Input,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
{
}
impl<A, B, EM, I, S, Z> HasExecHooks<EM, I, S, Z> for CombinedExecutor<A, B, I>
where
A: Executor<I> + HasExecHooks<EM, I, S, Z>,
B: Executor<I>,
I: Input,
{
#[inline]
fn pre_exec(
&mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<(), Error> {
self.primary.pre_exec(fuzzer, state, mgr, input)
}
#[inline]
fn post_exec(
&mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<(), Error> {
self.primary.post_exec(fuzzer, state, mgr, input)
}
}

View File

@ -13,9 +13,7 @@ use std::{
use crate::bolts::os::{dup2, pipes::Pipe};
use crate::{
executors::{
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
},
executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
inputs::{HasTargetBytes, Input},
observers::ObserversTuple,
Error,
@ -328,13 +326,19 @@ where
}
}
impl<I, OT> Executor<I> for ForkserverExecutor<I, OT>
impl<EM, I, OT, S, Z> Executor<EM, I, S, Z> for ForkserverExecutor<I, OT>
where
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
#[inline]
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> {
fn run_target(
&mut self,
_fuzzer: &mut Z,
_state: &mut S,
_mgr: &mut EM,
input: &I,
) -> Result<ExitKind, Error> {
let mut exit_kind = ExitKind::Ok;
// Write to testcase
@ -377,13 +381,6 @@ where
}
}
impl<EM, I, OT, S, Z> HasExecHooks<EM, I, S, Z> for ForkserverExecutor<I, OT>
where
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
}
impl<I, OT> HasObservers<OT> for ForkserverExecutor<I, OT>
where
I: Input + HasTargetBytes,

View File

@ -18,9 +18,7 @@ use crate::bolts::os::windows_exceptions::setup_exception_handler;
use crate::{
corpus::Corpus,
events::{EventFirer, EventRestarter},
executors::{
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
},
executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::Input,
@ -43,39 +41,26 @@ where
phantom: PhantomData<(I, S)>,
}
impl<'a, H, I, OT, S> Executor<I> for InProcessExecutor<'a, H, I, OT, S>
impl<'a, EM, H, I, OT, S, Z> Executor<EM, I, S, Z> for InProcessExecutor<'a, H, I, OT, S>
where
H: FnMut(&I) -> ExitKind,
I: Input,
OT: ObserversTuple,
{
#[inline]
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> {
let ret = (self.harness_fn)(input);
Ok(ret)
}
}
impl<'a, EM, H, I, OT, S, Z> HasExecHooks<EM, I, S, Z> for InProcessExecutor<'a, H, I, OT, S>
where
H: FnMut(&I) -> ExitKind,
I: Input,
OT: ObserversTuple,
{
#[inline]
fn pre_exec(
fn run_target(
&mut self,
_fuzzer: &mut Z,
_state: &mut S,
_event_mgr: &mut EM,
_input: &I,
) -> Result<(), Error> {
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<ExitKind, Error> {
#[cfg(unix)]
unsafe {
let data = &mut unix_signal_handler::GLOBAL_STATE;
write_volatile(
&mut data.current_input_ptr,
_input as *const _ as *const c_void,
input as *const _ as *const c_void,
);
write_volatile(
&mut data.observers_ptr,
@ -83,9 +68,9 @@ where
);
// Direct raw pointers access /aliasing is pretty undefined behavior.
// Since the state and event may have moved in memory, refresh them right before the signal may happen
write_volatile(&mut data.state_ptr, _state as *mut _ as *mut c_void);
write_volatile(&mut data.event_mgr_ptr, _event_mgr as *mut _ as *mut c_void);
write_volatile(&mut data.fuzzer_ptr, _fuzzer as *mut _ as *mut c_void);
write_volatile(&mut data.state_ptr, state as *mut _ as *mut c_void);
write_volatile(&mut data.event_mgr_ptr, mgr as *mut _ as *mut c_void);
write_volatile(&mut data.fuzzer_ptr, fuzzer as *mut _ as *mut c_void);
compiler_fence(Ordering::SeqCst);
}
#[cfg(all(windows, feature = "std"))]
@ -93,7 +78,7 @@ where
let data = &mut windows_exception_handler::GLOBAL_STATE;
write_volatile(
&mut data.current_input_ptr,
_input as *const _ as *const c_void,
input as *const _ as *const c_void,
);
write_volatile(
&mut data.observers_ptr,
@ -101,22 +86,14 @@ where
);
// Direct raw pointers access /aliasing is pretty undefined behavior.
// Since the state and event may have moved in memory, refresh them right before the signal may happen
write_volatile(&mut data.state_ptr, _state as *mut _ as *mut c_void);
write_volatile(&mut data.event_mgr_ptr, _event_mgr as *mut _ as *mut c_void);
write_volatile(&mut data.fuzzer_ptr, _fuzzer as *mut _ as *mut c_void);
write_volatile(&mut data.state_ptr, state as *mut _ as *mut c_void);
write_volatile(&mut data.event_mgr_ptr, mgr as *mut _ as *mut c_void);
write_volatile(&mut data.fuzzer_ptr, fuzzer as *mut _ as *mut c_void);
compiler_fence(Ordering::SeqCst);
}
Ok(())
}
#[inline]
fn post_exec(
&mut self,
_fuzzer: &mut Z,
_state: &mut S,
_event_mgr: &mut EM,
_input: &I,
) -> Result<(), Error> {
let ret = (self.harness_fn)(input);
#[cfg(unix)]
unsafe {
write_volatile(
@ -133,7 +110,8 @@ where
);
compiler_fence(Ordering::SeqCst);
}
Ok(())
Ok(ret)
}
}
@ -742,6 +720,8 @@ mod tests {
phantom: PhantomData,
};
let input = NopInput {};
assert!(in_process_executor.run_target(&input).is_ok());
assert!(in_process_executor
.run_target(&mut (), &mut (), &mut (), &input)
.is_ok());
}
}

View File

@ -13,8 +13,6 @@ pub use forkserver::{Forkserver, ForkserverExecutor, OutFile};
pub mod combined;
pub use combined::CombinedExecutor;
use core::marker::PhantomData;
use crate::{
bolts::serdeany::SerdeAny,
inputs::{HasTargetBytes, Input},
@ -184,25 +182,35 @@ where
}
/// An executor takes the given inputs, and runs the harness/target.
pub trait Executor<I>
pub trait Executor<EM, I, S, Z>
where
I: Input,
{
/// Instruct the target about the input and run
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error>;
fn run_target(
&mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<ExitKind, Error>;
}
/// A simple executor that does nothing.
/// If intput len is 0, `run_target` will return Err
struct NopExecutor<EM, I, S> {
phantom: PhantomData<(EM, I, S)>,
}
struct NopExecutor {}
impl<EM, I, S> Executor<I> for NopExecutor<EM, I, S>
impl<EM, I, S, Z> Executor<EM, I, S, Z> for NopExecutor
where
I: Input + HasTargetBytes,
{
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> {
fn run_target(
&mut self,
_fuzzer: &mut Z,
_state: &mut S,
_mgr: &mut EM,
input: &I,
) -> Result<ExitKind, Error> {
if input.target_bytes().as_slice().is_empty() {
Err(Error::Empty("Input Empty".into()))
} else {
@ -211,13 +219,8 @@ where
}
}
impl<EM, I, S, Z> HasExecHooks<EM, I, S, Z> for NopExecutor<EM, I, S> where I: Input + HasTargetBytes
{}
#[cfg(test)]
mod test {
use core::marker::PhantomData;
use super::{Executor, NopExecutor};
use crate::inputs::BytesInput;
@ -225,10 +228,12 @@ mod test {
fn nop_executor() {
let empty_input = BytesInput::new(vec![]);
let nonempty_input = BytesInput::new(vec![1u8]);
let mut executor = NopExecutor::<(), _, ()> {
phantom: PhantomData,
};
assert!(executor.run_target(&empty_input).is_err());
assert!(executor.run_target(&nonempty_input).is_ok());
let mut executor = NopExecutor {};
assert!(executor
.run_target(&mut (), &mut (), &mut (), &empty_input)
.is_err());
assert!(executor
.run_target(&mut (), &mut (), &mut (), &nonempty_input)
.is_ok());
}
}

View File

@ -1,11 +1,9 @@
//! A `TimeoutExecutor` sets a timeout before each target run
use core::{marker::PhantomData, time::Duration};
use core::time::Duration;
use crate::{
executors::{
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
},
executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
inputs::Input,
observers::ObserversTuple,
Error,
@ -39,28 +37,18 @@ extern "C" {
const ITIMER_REAL: c_int = 0;
/// The timeout excutor is a wrapper that set a timeout before each run
pub struct TimeoutExecutor<E, I>
where
E: Executor<I>,
I: Input,
{
pub struct TimeoutExecutor<E> {
executor: E,
exec_tmout: Duration,
phantom: PhantomData<I>,
}
impl<E, I> TimeoutExecutor<E, I>
where
E: Executor<I>,
I: Input,
{
impl<E> TimeoutExecutor<E> {
/// Create a new `TimeoutExecutor`, wrapping the given `executor` and checking for timeouts.
/// This should usually be used for `InProcess` fuzzing.
pub fn new(executor: E, exec_tmout: Duration) -> Self {
Self {
executor,
exec_tmout,
phantom: PhantomData,
}
}
@ -70,54 +58,18 @@ where
}
}
impl<E, I> Executor<I> for TimeoutExecutor<E, I>
impl<E, EM, I, S, Z> Executor<EM, I, S, Z> for TimeoutExecutor<E>
where
E: Executor<I>,
E: Executor<EM, I, S, Z>,
I: Input,
{
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> {
self.executor.run_target(input)
}
}
impl<E, I, OT> HasObservers<OT> for TimeoutExecutor<E, I>
where
E: Executor<I> + HasObservers<OT>,
I: Input,
OT: ObserversTuple,
{
#[inline]
fn observers(&self) -> &OT {
self.executor.observers()
}
#[inline]
fn observers_mut(&mut self) -> &mut OT {
self.executor.observers_mut()
}
}
impl<E, EM, I, OT, S, Z> HasObserversHooks<EM, I, OT, S, Z> for TimeoutExecutor<E, I>
where
E: Executor<I> + HasObservers<OT>,
I: Input,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
{
}
impl<E, EM, I, S, Z> HasExecHooks<EM, I, S, Z> for TimeoutExecutor<E, I>
where
E: Executor<I> + HasExecHooks<EM, I, S, Z>,
I: Input,
{
#[inline]
fn pre_exec(
fn run_target(
&mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<(), Error> {
) -> Result<ExitKind, Error> {
#[cfg(unix)]
unsafe {
let milli_sec = self.exec_tmout.as_millis();
@ -143,17 +95,9 @@ where
// TODO
let _ = self.exec_tmout.as_millis();
}
self.executor.pre_exec(fuzzer, state, mgr, input)
}
#[inline]
fn post_exec(
&mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<(), Error> {
let ret = self.executor.run_target(fuzzer, state, mgr, input);
#[cfg(unix)]
unsafe {
let it_value = Timeval {
@ -177,6 +121,31 @@ where
{
// TODO
}
self.executor.post_exec(fuzzer, state, mgr, input)
ret
}
}
impl<E, OT> HasObservers<OT> for TimeoutExecutor<E>
where
E: HasObservers<OT>,
OT: ObserversTuple,
{
#[inline]
fn observers(&self) -> &OT {
self.executor.observers()
}
#[inline]
fn observers_mut(&mut self) -> &mut OT {
self.executor.observers_mut()
}
}
impl<E, EM, I, OT, S, Z> HasObserversHooks<EM, I, OT, S, Z> for TimeoutExecutor<E>
where
E: HasObservers<OT>,
I: Input,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
{
}

View File

@ -265,61 +265,6 @@ where
}
}
/*if self.indexes.is_none() && self.novelties.is_none() {
for i in 0..size {
let history = map_state.history_map[i];
let item = observer.map()[i];
let reduced = R::reduce(history, item);
if history != reduced {
map_state.history_map[i] = reduced;
interesting = true;
}
}
} else if self.indexes.is_some() && self.novelties.is_none() {
for i in 0..size {
let history = map_state.history_map[i];
let item = observer.map()[i];
// TODO maybe walk again the histroy map only when it is interesting is more efficient
if item != initial {
self.indexes.as_mut().unwrap().push(i);
}
let reduced = R::reduce(history, item);
if history != reduced {
map_state.history_map[i] = reduced;
interesting = true;
}
}
} else if self.indexes.is_none() && self.novelties.is_some() {
for i in 0..size {
let history = map_state.history_map[i];
let item = observer.map()[i];
let reduced = R::reduce(history, item);
if history != reduced {
map_state.history_map[i] = reduced;
interesting = true;
self.novelties.as_mut().unwrap().push(i);
}
}
} else {
for i in 0..size {
let history = map_state.history_map[i];
let item = observer.map()[i];
if item != initial {
self.indexes.as_mut().unwrap().push(i);
}
let reduced = R::reduce(history, item);
if history != reduced {
map_state.history_map[i] = reduced;
interesting = true;
self.novelties.as_mut().unwrap().push(i);
}
}
}*/
if interesting {
let mut filled = 0;
for i in 0..size {

View File

@ -4,9 +4,7 @@ use crate::{
bolts::current_time,
corpus::{Corpus, CorpusScheduler, Testcase},
events::{Event, EventFirer, EventManager},
executors::{
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
},
executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
feedbacks::Feedback,
inputs::Input,
mark_feature_time,
@ -321,10 +319,7 @@ impl<C, CS, E, EM, F, I, OF, OT, S, SC> Evaluator<E, EM, I, S>
where
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
E: Executor<I>
+ HasObservers<OT>
+ HasExecHooks<EM, I, S, Self>
+ HasObserversHooks<EM, I, OT, S, Self>,
E: Executor<EM, I, S, Self> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Self>,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Self>,
EM: EventManager<E, I, S, Self>,
F: Feedback<I, S>,
@ -521,10 +516,7 @@ where
input: &I,
) -> Result<ExecuteInputResult, Error>
where
E: Executor<I>
+ HasObservers<OT>
+ HasExecHooks<EM, I, S, Self>
+ HasObserversHooks<EM, I, OT, S, Self>,
E: Executor<EM, I, S, Self> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Self>,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Self>,
EM: EventManager<E, I, S, Self>,
{
@ -533,17 +525,9 @@ where
mark_feature_time!(state, PerfFeature::PreExecObservers);
start_timer!(state);
executor.pre_exec(self, state, event_mgr, input)?;
mark_feature_time!(state, PerfFeature::PreExec);
start_timer!(state);
let exit_kind = executor.run_target(input)?;
let exit_kind = executor.run_target(self, state, event_mgr, input)?;
mark_feature_time!(state, PerfFeature::TargetExecution);
start_timer!(state);
executor.post_exec(self, state, event_mgr, input)?;
mark_feature_time!(state, PerfFeature::PostExec);
*state.executions_mut() += 1;
start_timer!(state);

View File

@ -2,7 +2,7 @@ use core::{marker::PhantomData, mem::drop};
use crate::{
corpus::Corpus,
executors::{Executor, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks},
executors::{Executor, HasExecHooksTuple, HasObservers, HasObserversHooks},
inputs::Input,
mark_feature_time,
observers::ObserversTuple,
@ -21,10 +21,7 @@ pub struct TracingStage<C, EM, I, OT, S, TE, Z>
where
I: Input,
C: Corpus<I>,
TE: Executor<I>
+ HasObservers<OT>
+ HasExecHooks<EM, I, S, Z>
+ HasObserversHooks<EM, I, OT, S, Z>,
TE: Executor<EM, I, S, Z> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Z>,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>,
{
@ -37,10 +34,7 @@ impl<E, C, EM, I, OT, S, TE, Z> Stage<E, EM, S, Z> for TracingStage<C, EM, I, OT
where
I: Input,
C: Corpus<I>,
TE: Executor<I>
+ HasObservers<OT>
+ HasExecHooks<EM, I, S, Z>
+ HasObserversHooks<EM, I, OT, S, Z>,
TE: Executor<EM, I, S, Z> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Z>,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>,
{
@ -68,19 +62,12 @@ where
mark_feature_time!(state, PerfFeature::PreExecObservers);
start_timer!(state);
self.tracer_executor
.pre_exec(fuzzer, state, manager, &input)?;
mark_feature_time!(state, PerfFeature::PreExec);
start_timer!(state);
drop(self.tracer_executor.run_target(&input)?);
drop(
self.tracer_executor
.run_target(fuzzer, state, manager, &input)?,
);
mark_feature_time!(state, PerfFeature::TargetExecution);
start_timer!(state);
self.tracer_executor
.post_exec(fuzzer, state, manager, &input)?;
mark_feature_time!(state, PerfFeature::PostExec);
*state.executions_mut() += 1;
start_timer!(state);
@ -96,10 +83,7 @@ impl<C, EM, I, OT, S, TE, Z> TracingStage<C, EM, I, OT, S, TE, Z>
where
I: Input,
C: Corpus<I>,
TE: Executor<I>
+ HasObservers<OT>
+ HasExecHooks<EM, I, S, Z>
+ HasObserversHooks<EM, I, OT, S, Z>,
TE: Executor<EM, I, S, Z> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Z>,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>,
{