Fix usage of TracingStage (#3062)
* real fix * more * debug * fix * fixer * mmmm * mm * mm * mm * fix * fix atheris * ?
This commit is contained in:
parent
f4cb9a827d
commit
226a20e6cf
@ -370,7 +370,7 @@ unsafe fn fuzz(
|
||||
|
||||
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||
|
||||
let tracing = ShadowTracingStage::new(&mut executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// Setup a randomic Input2State stage
|
||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
||||
|
@ -218,7 +218,7 @@ fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
|
||||
|
||||
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||
|
||||
let tracing = ShadowTracingStage::new(&mut executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// Setup a randomic Input2State stage
|
||||
let i2s =
|
||||
|
@ -344,7 +344,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
|
||||
|
||||
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||
|
||||
let tracing = ShadowTracingStage::new(&mut executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// Setup a randomic Input2State stage
|
||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
||||
|
@ -391,7 +391,7 @@ fn fuzz(
|
||||
println!("We imported {} inputs from disk.", state.corpus().count());
|
||||
}
|
||||
|
||||
let tracing = ShadowTracingStage::new(&mut executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// The order of the stages matter!
|
||||
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
||||
|
@ -403,7 +403,7 @@ fn fuzz(
|
||||
println!("We imported {} input(s) from disk.", state.corpus().count());
|
||||
}
|
||||
|
||||
let tracing = ShadowTracingStage::new(&mut executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// The order of the stages matter!
|
||||
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
||||
|
@ -316,7 +316,7 @@ impl<M: Monitor> Instance<'_, M> {
|
||||
|
||||
let mut shadow_executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||
|
||||
let tracing = ShadowTracingStage::new(&mut shadow_executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// Setup a randomic Input2State stage
|
||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
||||
|
@ -192,7 +192,7 @@ impl<M: Monitor> Instance<'_, M> {
|
||||
I2SRandReplace::new()
|
||||
)));
|
||||
|
||||
let tracing = ShadowTracingStage::new(&mut executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// Setup a MOPT mutator
|
||||
let mutator = StdMOptMutator::new(
|
||||
|
@ -232,7 +232,7 @@ pub fn fuzz() {
|
||||
)));
|
||||
|
||||
// Setup an havoc mutator with a mutational stage
|
||||
let tracing = ShadowTracingStage::new(&mut executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
let mutator = StdScheduledMutator::new(havoc_mutations());
|
||||
let mut stages = tuple_list!(tracing, i2s, StdMutationalStage::new(mutator),);
|
||||
|
||||
|
@ -240,7 +240,7 @@ pub fn fuzz() {
|
||||
)));
|
||||
|
||||
// Setup an havoc mutator with a mutational stage
|
||||
let tracing = ShadowTracingStage::new(&mut executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
let mutator = StdScheduledMutator::new(havoc_mutations());
|
||||
let mut stages = tuple_list!(tracing, i2s, StdMutationalStage::new(mutator),);
|
||||
|
||||
|
@ -14,7 +14,7 @@ use clap::{Arg, ArgAction, Command};
|
||||
use libafl::{
|
||||
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus},
|
||||
events::{launcher::Launcher, EventConfig},
|
||||
executors::{inprocess::InProcessExecutor, ExitKind},
|
||||
executors::{inprocess::InProcessExecutor, ExitKind, ShadowExecutor},
|
||||
feedback_or,
|
||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||
fuzzer::{Fuzzer, StdFuzzer},
|
||||
@ -28,7 +28,7 @@ use libafl::{
|
||||
},
|
||||
observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver},
|
||||
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
|
||||
stages::{StdMutationalStage, TracingStage},
|
||||
stages::{ShadowTracingStage, StdMutationalStage, TracingStage},
|
||||
state::{HasCorpus, StdState},
|
||||
Error, HasMetadata,
|
||||
};
|
||||
@ -216,14 +216,9 @@ pub extern "C" fn LLVMFuzzerRunDriver(
|
||||
ExitKind::Ok
|
||||
};
|
||||
|
||||
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||
// Setup a tracing stage in which we log comparisons
|
||||
let tracing = TracingStage::new(InProcessExecutor::new(
|
||||
&mut harness,
|
||||
tuple_list!(cmplog_observer),
|
||||
&mut fuzzer,
|
||||
&mut state,
|
||||
&mut mgr,
|
||||
)?);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// Setup a randomic Input2State stage
|
||||
let i2s =
|
||||
|
@ -19,7 +19,7 @@ use libafl::{
|
||||
Error, HasMetadata,
|
||||
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||
events::SimpleRestartingEventManager,
|
||||
executors::{ExitKind, inprocess::InProcessExecutor},
|
||||
executors::{ExitKind, ShadowExecutor, inprocess::InProcessExecutor},
|
||||
feedback_or,
|
||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
|
||||
fuzzer::{Fuzzer, StdFuzzer},
|
||||
@ -34,7 +34,7 @@ use libafl::{
|
||||
IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, powersched::PowerSchedule,
|
||||
},
|
||||
stages::{
|
||||
StdMutationalStage, TracingStage, calibrate::CalibrationStage,
|
||||
ShadowTracingStage, StdMutationalStage, calibrate::CalibrationStage,
|
||||
power::StdPowerMutationalStage,
|
||||
},
|
||||
state::{HasCorpus, StdState},
|
||||
@ -331,8 +331,6 @@ fn fuzz(
|
||||
ExitKind::Ok
|
||||
};
|
||||
|
||||
let mut tracing_harness = harness;
|
||||
|
||||
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
||||
let mut executor = InProcessExecutor::with_timeout(
|
||||
&mut harness,
|
||||
@ -343,18 +341,10 @@ fn fuzz(
|
||||
timeout,
|
||||
)?;
|
||||
|
||||
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||
|
||||
// Setup a tracing stage in which we log comparisons
|
||||
let tracing = TracingStage::new(
|
||||
InProcessExecutor::with_timeout(
|
||||
&mut tracing_harness,
|
||||
tuple_list!(cmplog_observer),
|
||||
&mut fuzzer,
|
||||
&mut state,
|
||||
&mut mgr,
|
||||
timeout * 10,
|
||||
)?,
|
||||
// Give it more time!
|
||||
);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// The order of the stages matter!
|
||||
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
||||
|
@ -18,10 +18,7 @@ use clap::{Arg, Command};
|
||||
use libafl::{
|
||||
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||
events::SimpleRestartingEventManager,
|
||||
executors::{
|
||||
inprocess::{HookableInProcessExecutor, InProcessExecutor},
|
||||
ExitKind,
|
||||
},
|
||||
executors::{inprocess::HookableInProcessExecutor, ExitKind, ShadowExecutor},
|
||||
feedback_or,
|
||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
|
||||
fuzzer::{Fuzzer, StdFuzzer},
|
||||
@ -36,8 +33,8 @@ use libafl::{
|
||||
powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler,
|
||||
},
|
||||
stages::{
|
||||
calibrate::CalibrationStage, power::StdPowerMutationalStage, StdMutationalStage,
|
||||
TracingStage,
|
||||
calibrate::CalibrationStage, power::StdPowerMutationalStage, ShadowTracingStage,
|
||||
StdMutationalStage,
|
||||
},
|
||||
state::{HasCorpus, StdState},
|
||||
Error, HasMetadata,
|
||||
@ -343,24 +340,10 @@ fn fuzz(
|
||||
ExitKind::Ok
|
||||
};
|
||||
|
||||
let mut tracing_harness = harness;
|
||||
let ctx_hook = CtxHook::new();
|
||||
|
||||
// Setup a tracing stage in which we log comparisons
|
||||
let tracing = TracingStage::new(
|
||||
InProcessExecutor::with_timeout(
|
||||
&mut tracing_harness,
|
||||
tuple_list!(cmplog_observer),
|
||||
&mut fuzzer,
|
||||
&mut state,
|
||||
&mut mgr,
|
||||
timeout * 10,
|
||||
)?,
|
||||
// Give it more time!
|
||||
);
|
||||
|
||||
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
||||
let mut executor = HookableInProcessExecutor::with_timeout_generic(
|
||||
let executor = HookableInProcessExecutor::with_timeout_generic(
|
||||
tuple_list!(ctx_hook),
|
||||
&mut harness,
|
||||
tuple_list!(edges_observer, time_observer),
|
||||
@ -370,6 +353,10 @@ fn fuzz(
|
||||
timeout,
|
||||
)?;
|
||||
|
||||
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||
// Setup a tracing stage in which we log comparisons
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// The order of the stages matter!
|
||||
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
||||
|
||||
|
@ -19,7 +19,7 @@ use content_inspector::inspect;
|
||||
use libafl::{
|
||||
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||
events::SimpleRestartingEventManager,
|
||||
executors::{inprocess::InProcessExecutor, ExitKind},
|
||||
executors::{inprocess::InProcessExecutor, ExitKind, ShadowExecutor},
|
||||
feedback_or,
|
||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
|
||||
fuzzer::{Fuzzer, StdFuzzer},
|
||||
@ -40,7 +40,7 @@ use libafl::{
|
||||
},
|
||||
stages::{
|
||||
calibrate::CalibrationStage, power::StdPowerMutationalStage, GeneralizationStage,
|
||||
StdMutationalStage, TracingStage,
|
||||
ShadowTracingStage, StdMutationalStage,
|
||||
},
|
||||
state::{HasCorpus, StdState},
|
||||
Error, HasMetadata,
|
||||
@ -400,8 +400,6 @@ fn fuzz_binary(
|
||||
ExitKind::Ok
|
||||
};
|
||||
|
||||
let mut tracing_harness = harness;
|
||||
|
||||
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
||||
let mut executor = InProcessExecutor::with_timeout(
|
||||
&mut harness,
|
||||
@ -413,14 +411,9 @@ fn fuzz_binary(
|
||||
)?;
|
||||
|
||||
// Setup a tracing stage in which we log comparisons
|
||||
let tracing = TracingStage::new(InProcessExecutor::with_timeout(
|
||||
&mut tracing_harness,
|
||||
tuple_list!(cmplog_observer),
|
||||
&mut fuzzer,
|
||||
&mut state,
|
||||
&mut mgr,
|
||||
timeout * 10,
|
||||
)?);
|
||||
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// The order of the stages matter!
|
||||
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
||||
@ -632,8 +625,6 @@ fn fuzz_text(
|
||||
ExitKind::Ok
|
||||
};
|
||||
|
||||
let mut tracing_harness = harness;
|
||||
|
||||
let generalization = GeneralizationStage::new(&edges_observer);
|
||||
|
||||
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
||||
@ -646,15 +637,8 @@ fn fuzz_text(
|
||||
timeout,
|
||||
)?;
|
||||
// Setup a tracing stage in which we log comparisons
|
||||
let tracing = TracingStage::new(InProcessExecutor::with_timeout(
|
||||
&mut tracing_harness,
|
||||
tuple_list!(cmplog_observer),
|
||||
&mut fuzzer,
|
||||
&mut state,
|
||||
&mut mgr,
|
||||
// Give it more time!
|
||||
timeout * 10,
|
||||
)?);
|
||||
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// The order of the stages matter!
|
||||
let mut stages = tuple_list!(generalization, calibration, tracing, i2s, power, grimoire);
|
||||
|
@ -152,7 +152,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
|
||||
}
|
||||
|
||||
// Setup a tracing stage in which we log comparisons
|
||||
let tracing = ShadowTracingStage::new(&mut executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// Setup a randomic Input2State stage
|
||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new())));
|
||||
|
@ -190,7 +190,7 @@ fn fuzz(
|
||||
}
|
||||
|
||||
// Setup a tracing stage in which we log comparisons
|
||||
let tracing = ShadowTracingStage::new(&mut executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// Setup a randomic Input2State stage
|
||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new())));
|
||||
|
@ -37,7 +37,7 @@ pub use sync::*;
|
||||
#[cfg(feature = "std")]
|
||||
pub use time_tracker::TimeTrackingStageWrapper;
|
||||
pub use tmin::{ObserverEqualityFactory, ObserverEqualityFeedback, StdTMinMutationalStage};
|
||||
pub use tracing::{ShadowTracingStage, TracingStage};
|
||||
pub use tracing::TracingStage;
|
||||
pub use tuneable::*;
|
||||
use tuple_list::NonEmptyTuple;
|
||||
#[cfg(feature = "unicode")]
|
||||
@ -57,6 +57,9 @@ pub mod mutational;
|
||||
pub mod push;
|
||||
pub mod tmin;
|
||||
|
||||
pub mod shadow;
|
||||
pub use shadow::*;
|
||||
|
||||
pub mod replay;
|
||||
pub use replay::*;
|
||||
|
||||
|
139
libafl/src/stages/shadow.rs
Normal file
139
libafl/src/stages/shadow.rs
Normal file
@ -0,0 +1,139 @@
|
||||
//! A stage that runs the shadow executor using also the shadow observers. Unlike tracing stage, this
|
||||
//! stage *CAN* be used with inprocess executor.
|
||||
|
||||
use alloc::{
|
||||
borrow::{Cow, ToOwned},
|
||||
string::ToString,
|
||||
};
|
||||
use core::{fmt::Debug, marker::PhantomData};
|
||||
|
||||
use libafl_bolts::Named;
|
||||
|
||||
#[cfg(feature = "introspection")]
|
||||
use crate::monitors::stats::PerfFeature;
|
||||
use crate::{
|
||||
Error, HasNamedMetadata,
|
||||
corpus::HasCurrentCorpusId,
|
||||
executors::{Executor, HasObservers, ShadowExecutor},
|
||||
mark_feature_time,
|
||||
observers::ObserversTuple,
|
||||
stages::{Restartable, RetryCountRestartHelper, Stage},
|
||||
start_timer,
|
||||
state::{HasCorpus, HasCurrentTestcase, HasExecutions, MaybeHasClientPerfMonitor},
|
||||
};
|
||||
|
||||
/// A stage that runs the shadow executor using also the shadow observers
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ShadowTracingStage<E, EM, I, SOT, S, Z> {
|
||||
name: Cow<'static, str>,
|
||||
phantom: PhantomData<(E, EM, I, SOT, S, Z)>,
|
||||
}
|
||||
|
||||
impl<E, EM, I, SOT, S, Z> Default for ShadowTracingStage<E, EM, I, SOT, S, Z>
|
||||
where
|
||||
E: Executor<EM, I, S, Z> + HasObservers,
|
||||
S: HasExecutions + HasCorpus<I>,
|
||||
SOT: ObserversTuple<I, S>,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// The counter for giving this stage unique id
|
||||
static mut SHADOW_TRACING_STAGE_ID: usize = 0;
|
||||
/// Name for shadow tracing stage
|
||||
pub static SHADOW_TRACING_STAGE_NAME: &str = "shadow";
|
||||
|
||||
impl<E, EM, I, SOT, S, Z> Named for ShadowTracingStage<E, EM, I, SOT, S, Z> {
|
||||
fn name(&self) -> &Cow<'static, str> {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, EM, I, SOT, S, Z> Stage<ShadowExecutor<E, I, S, SOT>, EM, S, Z>
|
||||
for ShadowTracingStage<E, EM, I, SOT, S, Z>
|
||||
where
|
||||
E: Executor<EM, I, S, Z> + HasObservers,
|
||||
E::Observers: ObserversTuple<I, S>,
|
||||
SOT: ObserversTuple<I, S>,
|
||||
S: HasExecutions
|
||||
+ HasCorpus<I>
|
||||
+ HasNamedMetadata
|
||||
+ Debug
|
||||
+ HasCurrentTestcase<I>
|
||||
+ HasCurrentCorpusId
|
||||
+ MaybeHasClientPerfMonitor,
|
||||
{
|
||||
#[inline]
|
||||
fn perform(
|
||||
&mut self,
|
||||
fuzzer: &mut Z,
|
||||
executor: &mut ShadowExecutor<E, I, S, SOT>,
|
||||
state: &mut S,
|
||||
manager: &mut EM,
|
||||
) -> Result<(), Error> {
|
||||
start_timer!(state);
|
||||
let input = state.current_input_cloned()?;
|
||||
|
||||
mark_feature_time!(state, PerfFeature::GetInputFromCorpus);
|
||||
|
||||
start_timer!(state);
|
||||
executor
|
||||
.shadow_observers_mut()
|
||||
.pre_exec_all(state, &input)?;
|
||||
executor.observers_mut().pre_exec_all(state, &input)?;
|
||||
mark_feature_time!(state, PerfFeature::PreExecObservers);
|
||||
|
||||
start_timer!(state);
|
||||
let exit_kind = executor.run_target(fuzzer, state, manager, &input)?;
|
||||
mark_feature_time!(state, PerfFeature::TargetExecution);
|
||||
|
||||
start_timer!(state);
|
||||
executor
|
||||
.shadow_observers_mut()
|
||||
.post_exec_all(state, &input, &exit_kind)?;
|
||||
executor
|
||||
.observers_mut()
|
||||
.post_exec_all(state, &input, &exit_kind)?;
|
||||
mark_feature_time!(state, PerfFeature::PostExecObservers);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, EM, I, SOT, S, Z> Restartable<S> for ShadowTracingStage<E, EM, I, SOT, S, Z>
|
||||
where
|
||||
S: HasNamedMetadata + HasCurrentCorpusId,
|
||||
{
|
||||
fn should_restart(&mut self, state: &mut S) -> Result<bool, Error> {
|
||||
RetryCountRestartHelper::no_retry(state, &self.name)
|
||||
}
|
||||
|
||||
fn clear_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
||||
RetryCountRestartHelper::clear_progress(state, &self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, EM, I, SOT, S, Z> ShadowTracingStage<E, EM, I, SOT, S, Z>
|
||||
where
|
||||
E: Executor<EM, I, S, Z> + HasObservers,
|
||||
S: HasExecutions + HasCorpus<I>,
|
||||
SOT: ObserversTuple<I, S>,
|
||||
{
|
||||
/// Creates a new default stage
|
||||
pub fn new() -> Self {
|
||||
// unsafe but impossible that you create two threads both instantiating this instance
|
||||
let stage_id = unsafe {
|
||||
let ret = SHADOW_TRACING_STAGE_ID;
|
||||
SHADOW_TRACING_STAGE_ID += 1;
|
||||
ret
|
||||
};
|
||||
Self {
|
||||
name: Cow::Owned(
|
||||
SHADOW_TRACING_STAGE_NAME.to_owned() + ":" + stage_id.to_string().as_str(),
|
||||
),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ use crate::monitors::stats::PerfFeature;
|
||||
use crate::{
|
||||
Error, HasNamedMetadata,
|
||||
corpus::HasCurrentCorpusId,
|
||||
executors::{Executor, HasObservers, ShadowExecutor},
|
||||
executors::{Executor, HasObservers},
|
||||
inputs::Input,
|
||||
mark_feature_time,
|
||||
observers::ObserversTuple,
|
||||
@ -23,6 +23,7 @@ use crate::{
|
||||
};
|
||||
|
||||
/// A stage that runs a tracer executor
|
||||
/// This should *NOT* be used with inprocess executor
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TracingStage<EM, I, TE, S, Z> {
|
||||
name: Cow<'static, str>,
|
||||
@ -146,108 +147,3 @@ impl<EM, I, TE, S, Z> TracingStage<EM, I, TE, S, Z> {
|
||||
&mut self.tracer_executor
|
||||
}
|
||||
}
|
||||
|
||||
/// A stage that runs the shadow executor using also the shadow observers
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ShadowTracingStage<E, EM, I, SOT, S, Z> {
|
||||
name: Cow<'static, str>,
|
||||
phantom: PhantomData<(E, EM, I, SOT, S, Z)>,
|
||||
}
|
||||
|
||||
/// The counter for giving this stage unique id
|
||||
static mut SHADOW_TRACING_STAGE_ID: usize = 0;
|
||||
/// Name for shadow tracing stage
|
||||
pub static SHADOW_TRACING_STAGE_NAME: &str = "shadow";
|
||||
|
||||
impl<E, EM, I, SOT, S, Z> Named for ShadowTracingStage<E, EM, I, SOT, S, Z> {
|
||||
fn name(&self) -> &Cow<'static, str> {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, EM, I, SOT, S, Z> Stage<ShadowExecutor<E, I, S, SOT>, EM, S, Z>
|
||||
for ShadowTracingStage<E, EM, I, SOT, S, Z>
|
||||
where
|
||||
E: Executor<EM, I, S, Z> + HasObservers,
|
||||
E::Observers: ObserversTuple<I, S>,
|
||||
SOT: ObserversTuple<I, S>,
|
||||
S: HasExecutions
|
||||
+ HasCorpus<I>
|
||||
+ HasNamedMetadata
|
||||
+ Debug
|
||||
+ HasCurrentTestcase<I>
|
||||
+ HasCurrentCorpusId
|
||||
+ MaybeHasClientPerfMonitor,
|
||||
{
|
||||
#[inline]
|
||||
fn perform(
|
||||
&mut self,
|
||||
fuzzer: &mut Z,
|
||||
executor: &mut ShadowExecutor<E, I, S, SOT>,
|
||||
state: &mut S,
|
||||
manager: &mut EM,
|
||||
) -> Result<(), Error> {
|
||||
start_timer!(state);
|
||||
let input = state.current_input_cloned()?;
|
||||
|
||||
mark_feature_time!(state, PerfFeature::GetInputFromCorpus);
|
||||
|
||||
start_timer!(state);
|
||||
executor
|
||||
.shadow_observers_mut()
|
||||
.pre_exec_all(state, &input)?;
|
||||
executor.observers_mut().pre_exec_all(state, &input)?;
|
||||
mark_feature_time!(state, PerfFeature::PreExecObservers);
|
||||
|
||||
start_timer!(state);
|
||||
let exit_kind = executor.run_target(fuzzer, state, manager, &input)?;
|
||||
mark_feature_time!(state, PerfFeature::TargetExecution);
|
||||
|
||||
start_timer!(state);
|
||||
executor
|
||||
.shadow_observers_mut()
|
||||
.post_exec_all(state, &input, &exit_kind)?;
|
||||
executor
|
||||
.observers_mut()
|
||||
.post_exec_all(state, &input, &exit_kind)?;
|
||||
mark_feature_time!(state, PerfFeature::PostExecObservers);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, EM, I, SOT, S, Z> Restartable<S> for ShadowTracingStage<E, EM, I, SOT, S, Z>
|
||||
where
|
||||
S: HasNamedMetadata + HasCurrentCorpusId,
|
||||
{
|
||||
fn should_restart(&mut self, state: &mut S) -> Result<bool, Error> {
|
||||
RetryCountRestartHelper::no_retry(state, &self.name)
|
||||
}
|
||||
|
||||
fn clear_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
||||
RetryCountRestartHelper::clear_progress(state, &self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, EM, I, SOT, S, Z> ShadowTracingStage<E, EM, I, SOT, S, Z>
|
||||
where
|
||||
E: Executor<EM, I, S, Z> + HasObservers,
|
||||
S: HasExecutions + HasCorpus<I>,
|
||||
SOT: ObserversTuple<I, S>,
|
||||
{
|
||||
/// Creates a new default stage
|
||||
pub fn new(_executor: &mut ShadowExecutor<E, I, S, SOT>) -> Self {
|
||||
// unsafe but impossible that you create two threads both instantiating this instance
|
||||
let stage_id = unsafe {
|
||||
let ret = SHADOW_TRACING_STAGE_ID;
|
||||
SHADOW_TRACING_STAGE_ID += 1;
|
||||
ret
|
||||
};
|
||||
Self {
|
||||
name: Cow::Owned(
|
||||
SHADOW_TRACING_STAGE_NAME.to_owned() + ":" + stage_id.to_string().as_str(),
|
||||
),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ macro_rules! fuzz_with {
|
||||
};
|
||||
use libafl::{
|
||||
corpus::Corpus,
|
||||
executors::{ExitKind, InProcessExecutor},
|
||||
executors::{ExitKind, InProcessExecutor, ShadowExecutor},
|
||||
feedback_and_fast, feedback_not, feedback_or, feedback_or_fast,
|
||||
feedbacks::{ConstFeedback, CrashFeedback, MaxMapFeedback, NewHashFeedback, TimeFeedback, TimeoutFeedback},
|
||||
generators::RandBytesGenerator,
|
||||
@ -166,7 +166,7 @@ macro_rules! fuzz_with {
|
||||
},
|
||||
stages::{
|
||||
CalibrationStage, GeneralizationStage, IfStage, StdMutationalStage,
|
||||
StdPowerMutationalStage, UnicodeIdentificationStage, TracingStage,
|
||||
StdPowerMutationalStage, UnicodeIdentificationStage, ShadowTracingStage,
|
||||
},
|
||||
state::{HasCorpus, StdState},
|
||||
StdFuzzer,
|
||||
@ -438,8 +438,6 @@ macro_rules! fuzz_with {
|
||||
}
|
||||
};
|
||||
|
||||
let mut tracing_harness = harness;
|
||||
|
||||
let add_extra_observer = $extra_obsv;
|
||||
let observers = add_extra_observer(
|
||||
tuple_list!(edges_observer, size_edges_observer, time_observer, backtrace_observer, oom_observer),
|
||||
@ -488,14 +486,9 @@ macro_rules! fuzz_with {
|
||||
}
|
||||
}
|
||||
|
||||
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||
// Setup a tracing stage in which we log comparisons
|
||||
let tracing = IfStage::new(|_, _, _, _| Ok(!$options.skip_tracing()), (TracingStage::new(InProcessExecutor::new(
|
||||
&mut tracing_harness,
|
||||
tuple_list!(cmplog_observer),
|
||||
&mut fuzzer,
|
||||
&mut state,
|
||||
&mut mgr,
|
||||
)?), ()));
|
||||
let tracing = IfStage::new(|_, _, _, _| Ok(!$options.skip_tracing()), (ShadowTracingStage::new(), ()));
|
||||
|
||||
// The order of the stages matter!
|
||||
let mut stages = tuple_list!(
|
||||
|
@ -261,7 +261,7 @@ where
|
||||
}
|
||||
|
||||
// Setup a tracing stage in which we log comparisons
|
||||
let tracing = ShadowTracingStage::new(&mut executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// Setup a randomic Input2State stage
|
||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
||||
|
@ -299,7 +299,7 @@ where
|
||||
}
|
||||
|
||||
// Setup a tracing stage in which we log comparisons
|
||||
let tracing = ShadowTracingStage::new(&mut executor);
|
||||
let tracing = ShadowTracingStage::new();
|
||||
|
||||
// Setup a randomic Input2State stage
|
||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
||||
|
Loading…
x
Reference in New Issue
Block a user