Alternative scheduled count strategy (#1252)
* early return generalization stage * scheduled count * aaa * compile * fix * implement alternative scheduled count strategy --------- Co-authored-by: toka <tokazerkje@outlook.com>
This commit is contained in:
parent
53659f8a5c
commit
a8e64be169
@ -13,7 +13,7 @@ use crate::monitors::PerfFeature;
|
||||
use crate::state::NopState;
|
||||
use crate::{
|
||||
bolts::current_time,
|
||||
corpus::{Corpus, CorpusId, Testcase},
|
||||
corpus::{Corpus, CorpusId, HasTestcase, Testcase},
|
||||
events::{Event, EventConfig, EventFirer, EventProcessor, ProgressReporter},
|
||||
executors::{Executor, ExitKind, HasObservers},
|
||||
feedbacks::Feedback,
|
||||
@ -31,7 +31,10 @@ use crate::{
|
||||
const STATS_TIMEOUT_DEFAULT: Duration = Duration::from_secs(15);
|
||||
|
||||
/// Holds a scheduler
|
||||
pub trait HasScheduler: UsesState {
|
||||
pub trait HasScheduler: UsesState
|
||||
where
|
||||
Self::State: HasCorpus,
|
||||
{
|
||||
/// The [`Scheduler`] for this fuzzer
|
||||
type Scheduler: Scheduler<State = Self::State>;
|
||||
|
||||
@ -249,7 +252,7 @@ where
|
||||
CS: Scheduler,
|
||||
F: Feedback<CS::State>,
|
||||
OF: Feedback<CS::State>,
|
||||
CS::State: HasClientPerfMonitor,
|
||||
CS::State: HasClientPerfMonitor + HasCorpus,
|
||||
{
|
||||
scheduler: CS,
|
||||
feedback: F,
|
||||
@ -262,7 +265,7 @@ where
|
||||
CS: Scheduler,
|
||||
F: Feedback<CS::State>,
|
||||
OF: Feedback<CS::State>,
|
||||
CS::State: HasClientPerfMonitor,
|
||||
CS::State: HasClientPerfMonitor + HasCorpus,
|
||||
{
|
||||
type State = CS::State;
|
||||
}
|
||||
@ -272,7 +275,7 @@ where
|
||||
CS: Scheduler,
|
||||
F: Feedback<CS::State>,
|
||||
OF: Feedback<CS::State>,
|
||||
CS::State: HasClientPerfMonitor,
|
||||
CS::State: HasClientPerfMonitor + HasCorpus,
|
||||
{
|
||||
type Scheduler = CS;
|
||||
|
||||
@ -290,7 +293,7 @@ where
|
||||
CS: Scheduler,
|
||||
F: Feedback<CS::State>,
|
||||
OF: Feedback<CS::State>,
|
||||
CS::State: HasClientPerfMonitor,
|
||||
CS::State: HasClientPerfMonitor + HasCorpus,
|
||||
{
|
||||
type Feedback = F;
|
||||
|
||||
@ -308,7 +311,7 @@ where
|
||||
CS: Scheduler,
|
||||
F: Feedback<CS::State>,
|
||||
OF: Feedback<CS::State>,
|
||||
CS::State: HasClientPerfMonitor,
|
||||
CS::State: HasClientPerfMonitor + HasCorpus,
|
||||
{
|
||||
type Objective = OF;
|
||||
|
||||
@ -327,7 +330,7 @@ where
|
||||
F: Feedback<CS::State>,
|
||||
OF: Feedback<CS::State>,
|
||||
OT: ObserversTuple<CS::State> + Serialize + DeserializeOwned,
|
||||
CS::State: HasCorpus + HasSolutions + HasClientPerfMonitor + HasExecutions,
|
||||
CS::State: HasCorpus + HasSolutions + HasClientPerfMonitor + HasExecutions + HasCorpus,
|
||||
{
|
||||
/// Evaluate if a set of observation channels has an interesting state
|
||||
fn process_execution<EM>(
|
||||
@ -549,7 +552,7 @@ where
|
||||
EM: ProgressReporter + EventProcessor<E, Self, State = CS::State>,
|
||||
F: Feedback<CS::State>,
|
||||
OF: Feedback<CS::State>,
|
||||
CS::State: HasClientPerfMonitor + HasExecutions + HasMetadata,
|
||||
CS::State: HasClientPerfMonitor + HasExecutions + HasMetadata + HasCorpus + HasTestcase,
|
||||
ST: StagesTuple<E, EM, CS::State, Self>,
|
||||
{
|
||||
fn fuzz_one(
|
||||
@ -588,6 +591,14 @@ where
|
||||
#[cfg(feature = "introspection")]
|
||||
state.introspection_monitor_mut().mark_manager_time();
|
||||
|
||||
{
|
||||
let mut testcase = state.testcase_mut(idx)?;
|
||||
let scheduled_count = testcase.scheduled_count();
|
||||
|
||||
// increase scheduled count, this was fuzz_level in afl
|
||||
testcase.set_scheduled_count(scheduled_count + 1);
|
||||
}
|
||||
|
||||
Ok(idx)
|
||||
}
|
||||
}
|
||||
@ -597,7 +608,7 @@ where
|
||||
CS: Scheduler,
|
||||
F: Feedback<CS::State>,
|
||||
OF: Feedback<CS::State>,
|
||||
CS::State: UsesInput + HasExecutions + HasClientPerfMonitor,
|
||||
CS::State: UsesInput + HasExecutions + HasClientPerfMonitor + HasCorpus,
|
||||
{
|
||||
/// Create a new `StdFuzzer` with standard behavior.
|
||||
pub fn new(scheduler: CS, feedback: F, objective: OF) -> Self {
|
||||
@ -665,7 +676,7 @@ where
|
||||
OF: Feedback<CS::State>,
|
||||
E: Executor<EM, Self> + HasObservers<State = CS::State>,
|
||||
EM: UsesState<State = CS::State>,
|
||||
CS::State: UsesInput + HasExecutions + HasClientPerfMonitor,
|
||||
CS::State: UsesInput + HasExecutions + HasClientPerfMonitor + HasCorpus,
|
||||
{
|
||||
/// Runs the input and triggers observers and feedback
|
||||
fn execute_input(
|
||||
|
@ -334,26 +334,6 @@ where
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
/// Set current fuzzed corpus id and `scheduled_count`
|
||||
fn set_current_scheduled(
|
||||
&mut self,
|
||||
state: &mut Self::State,
|
||||
next_idx: Option<CorpusId>,
|
||||
) -> Result<(), Error> {
|
||||
let current_idx = *state.corpus().current();
|
||||
|
||||
if let Some(idx) = current_idx {
|
||||
let mut testcase = state.testcase_mut(idx)?;
|
||||
let scheduled_count = testcase.scheduled_count();
|
||||
|
||||
// increase scheduled count, this was fuzz_level in afl
|
||||
testcase.set_scheduled_count(scheduled_count + 1);
|
||||
}
|
||||
|
||||
*state.corpus_mut().current_mut() = next_idx;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// The weight for each corpus entry
|
||||
|
@ -34,7 +34,7 @@ pub use tuneable::*;
|
||||
|
||||
use crate::{
|
||||
bolts::rands::Rand,
|
||||
corpus::{Corpus, CorpusId, Testcase},
|
||||
corpus::{Corpus, CorpusId, HasTestcase, Testcase},
|
||||
inputs::UsesInput,
|
||||
observers::ObserversTuple,
|
||||
random_corpus_id,
|
||||
@ -43,7 +43,10 @@ use crate::{
|
||||
};
|
||||
|
||||
/// The scheduler also implemnts `on_remove` and `on_replace` if it implements this stage.
|
||||
pub trait RemovableScheduler: Scheduler {
|
||||
pub trait RemovableScheduler: Scheduler
|
||||
where
|
||||
Self::State: HasCorpus,
|
||||
{
|
||||
/// Removed the given entry from the corpus at the given index
|
||||
fn on_remove(
|
||||
&mut self,
|
||||
@ -67,7 +70,10 @@ pub trait RemovableScheduler: Scheduler {
|
||||
|
||||
/// The scheduler define how the fuzzer requests a testcase from the corpus.
|
||||
/// It has hooks to corpus add/replace/remove to allow complex scheduling algorithms to collect data.
|
||||
pub trait Scheduler: UsesState {
|
||||
pub trait Scheduler: UsesState
|
||||
where
|
||||
Self::State: HasCorpus,
|
||||
{
|
||||
/// Added an entry to the corpus at the given index
|
||||
fn on_add(&mut self, _state: &mut Self::State, _idx: CorpusId) -> Result<(), Error>;
|
||||
// Add parent_id here if it has no inner
|
||||
@ -94,7 +100,10 @@ pub trait Scheduler: UsesState {
|
||||
&mut self,
|
||||
state: &mut Self::State,
|
||||
next_idx: Option<CorpusId>,
|
||||
) -> Result<(), Error>;
|
||||
) -> Result<(), Error> {
|
||||
*state.corpus_mut().current_mut() = next_idx;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Feed the fuzzer simply with a random testcase on request
|
||||
@ -105,14 +114,14 @@ pub struct RandScheduler<S> {
|
||||
|
||||
impl<S> UsesState for RandScheduler<S>
|
||||
where
|
||||
S: UsesInput,
|
||||
S: UsesInput + HasTestcase,
|
||||
{
|
||||
type State = S;
|
||||
}
|
||||
|
||||
impl<S> Scheduler for RandScheduler<S>
|
||||
where
|
||||
S: HasCorpus + HasRand,
|
||||
S: HasCorpus + HasRand + HasTestcase,
|
||||
{
|
||||
fn on_add(&mut self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> {
|
||||
// Set parent id
|
||||
@ -136,16 +145,6 @@ where
|
||||
Ok(id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set current fuzzed corpus id and `scheduled_count`. You should call this from `next`
|
||||
fn set_current_scheduled(
|
||||
&mut self,
|
||||
state: &mut Self::State,
|
||||
next_idx: Option<CorpusId>,
|
||||
) -> Result<(), Error> {
|
||||
*state.corpus_mut().current_mut() = next_idx;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> RandScheduler<S> {
|
||||
|
@ -336,11 +336,6 @@ where
|
||||
|
||||
if let Some(idx) = current_idx {
|
||||
let mut testcase = state.testcase_mut(idx)?;
|
||||
let scheduled_count = testcase.scheduled_count();
|
||||
|
||||
// increase scheduled count, this was fuzz_level in afl
|
||||
testcase.set_scheduled_count(scheduled_count + 1);
|
||||
|
||||
let tcmeta = testcase.metadata_mut::<SchedulerTestcaseMetadata>()?;
|
||||
|
||||
if tcmeta.handicap() >= 4 {
|
||||
|
@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
bolts::rands::Rand,
|
||||
corpus::{Corpus, CorpusId},
|
||||
corpus::{Corpus, CorpusId, HasTestcase},
|
||||
inputs::UsesInput,
|
||||
schedulers::{Scheduler, TestcaseScore},
|
||||
state::{HasCorpus, HasMetadata, HasRand, UsesState},
|
||||
@ -89,7 +89,7 @@ where
|
||||
|
||||
impl<F, S> UsesState for ProbabilitySamplingScheduler<F, S>
|
||||
where
|
||||
S: UsesInput,
|
||||
S: UsesInput + HasTestcase,
|
||||
{
|
||||
type State = S;
|
||||
}
|
||||
@ -97,7 +97,7 @@ where
|
||||
impl<F, S> Scheduler for ProbabilitySamplingScheduler<F, S>
|
||||
where
|
||||
F: TestcaseScore<S>,
|
||||
S: HasCorpus + HasMetadata + HasRand,
|
||||
S: HasCorpus + HasMetadata + HasRand + HasTestcase,
|
||||
{
|
||||
fn on_add(&mut self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> {
|
||||
let current_idx = *state.corpus().current();
|
||||
@ -135,16 +135,6 @@ where
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set current fuzzed corpus id and `scheduled_count`
|
||||
fn set_current_scheduled(
|
||||
&mut self,
|
||||
state: &mut Self::State,
|
||||
next_idx: Option<CorpusId>,
|
||||
) -> Result<(), Error> {
|
||||
*state.corpus_mut().current_mut() = next_idx;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, S> Default for ProbabilitySamplingScheduler<F, S>
|
||||
|
@ -4,7 +4,7 @@ use alloc::borrow::ToOwned;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
corpus::{Corpus, CorpusId},
|
||||
corpus::{Corpus, CorpusId, HasTestcase},
|
||||
inputs::UsesInput,
|
||||
schedulers::{RemovableScheduler, Scheduler},
|
||||
state::{HasCorpus, UsesState},
|
||||
@ -24,11 +24,11 @@ where
|
||||
type State = S;
|
||||
}
|
||||
|
||||
impl<S> RemovableScheduler for QueueScheduler<S> where S: HasCorpus {}
|
||||
impl<S> RemovableScheduler for QueueScheduler<S> where S: HasCorpus + HasTestcase {}
|
||||
|
||||
impl<S> Scheduler for QueueScheduler<S>
|
||||
where
|
||||
S: HasCorpus,
|
||||
S: HasCorpus + HasTestcase,
|
||||
{
|
||||
fn on_add(&mut self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> {
|
||||
// Set parent id
|
||||
@ -57,16 +57,6 @@ where
|
||||
Ok(id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set current fuzzed corpus id and `scheduled_count`
|
||||
fn set_current_scheduled(
|
||||
&mut self,
|
||||
state: &mut Self::State,
|
||||
next_idx: Option<CorpusId>,
|
||||
) -> Result<(), Error> {
|
||||
*state.corpus_mut().current_mut() = next_idx;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> QueueScheduler<S> {
|
||||
|
@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::RemovableScheduler;
|
||||
use crate::{
|
||||
corpus::{Corpus, CorpusId},
|
||||
corpus::{Corpus, CorpusId, HasTestcase},
|
||||
impl_serdeany,
|
||||
inputs::UsesInput,
|
||||
schedulers::Scheduler,
|
||||
@ -92,11 +92,11 @@ where
|
||||
type State = S;
|
||||
}
|
||||
|
||||
impl<S> RemovableScheduler for TuneableScheduler<S> where S: HasCorpus + HasMetadata {}
|
||||
impl<S> RemovableScheduler for TuneableScheduler<S> where S: HasCorpus + HasMetadata + HasTestcase {}
|
||||
|
||||
impl<S> Scheduler for TuneableScheduler<S>
|
||||
where
|
||||
S: HasCorpus + HasMetadata,
|
||||
S: HasCorpus + HasMetadata + HasTestcase,
|
||||
{
|
||||
fn on_add(&mut self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> {
|
||||
// Set parent id
|
||||
@ -126,14 +126,4 @@ where
|
||||
self.set_current_scheduled(state, Some(id))?;
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
/// Set current fuzzed corpus id and `scheduled_count`
|
||||
fn set_current_scheduled(
|
||||
&mut self,
|
||||
state: &mut Self::State,
|
||||
next_idx: Option<CorpusId>,
|
||||
) -> Result<(), Error> {
|
||||
*state.corpus_mut().current_mut() = next_idx;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -408,11 +408,6 @@ where
|
||||
|
||||
if let Some(idx) = current_idx {
|
||||
let mut testcase = state.testcase_mut(idx)?;
|
||||
let scheduled_count = testcase.scheduled_count();
|
||||
|
||||
// increase scheduled count, this was fuzz_level in afl
|
||||
testcase.set_scheduled_count(scheduled_count + 1);
|
||||
|
||||
let tcmeta = testcase.metadata_mut::<SchedulerTestcaseMetadata>()?;
|
||||
|
||||
if tcmeta.handicap() >= 4 {
|
||||
|
@ -257,10 +257,8 @@ where
|
||||
psmeta.set_bitmap_entries(psmeta.bitmap_entries() + 1);
|
||||
|
||||
let mut testcase = state.corpus().get(corpus_idx)?.borrow_mut();
|
||||
let scheduled_count = testcase.scheduled_count();
|
||||
|
||||
testcase.set_exec_time(total_time / (iter as u32));
|
||||
testcase.set_scheduled_count(scheduled_count + 1);
|
||||
// log::trace!("time: {:#?}", testcase.exec_time());
|
||||
|
||||
// If the testcase doesn't have its own `SchedulerTestcaseMetadata`, create it.
|
||||
|
@ -82,6 +82,10 @@ where
|
||||
{
|
||||
let corpus = state.corpus();
|
||||
let mut testcase = corpus.get(corpus_idx)?.borrow_mut();
|
||||
if testcase.scheduled_count() > 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
corpus.load_input_into(&mut testcase)?;
|
||||
}
|
||||
mark_feature_time!(state, PerfFeature::GetInputFromCorpus);
|
||||
|
@ -66,7 +66,7 @@ use crate::{
|
||||
inputs::UsesInput,
|
||||
observers::ObserversTuple,
|
||||
schedulers::Scheduler,
|
||||
state::{HasClientPerfMonitor, HasExecutions, HasMetadata, HasRand, UsesState},
|
||||
state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasMetadata, HasRand, UsesState},
|
||||
Error, EvaluatorObservers, ExecutesInput, ExecutionProcessor, HasScheduler,
|
||||
};
|
||||
|
||||
@ -248,7 +248,7 @@ where
|
||||
impl<CS, E, EM, OT, PS, Z> Stage<E, EM, Z> for PushStageAdapter<CS, EM, OT, PS, Z>
|
||||
where
|
||||
CS: Scheduler,
|
||||
CS::State: HasClientPerfMonitor + HasExecutions + HasMetadata + HasRand,
|
||||
CS::State: HasClientPerfMonitor + HasExecutions + HasMetadata + HasRand + HasCorpus,
|
||||
E: Executor<EM, Z> + HasObservers<Observers = OT, State = CS::State>,
|
||||
EM: EventFirer<State = CS::State>
|
||||
+ EventRestarter
|
||||
|
@ -23,7 +23,7 @@ use crate::{
|
||||
inputs::UsesInput,
|
||||
observers::ObserversTuple,
|
||||
schedulers::Scheduler,
|
||||
state::{HasClientPerfMonitor, HasExecutions, HasMetadata, HasRand},
|
||||
state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasMetadata, HasRand},
|
||||
Error, EvaluatorObservers, ExecutionProcessor, HasScheduler,
|
||||
};
|
||||
|
||||
@ -38,7 +38,7 @@ where
|
||||
CS: Scheduler,
|
||||
EM: EventFirer<State = CS::State> + EventRestarter + HasEventManagerId,
|
||||
OT: ObserversTuple<CS::State>,
|
||||
CS::State: HasClientPerfMonitor + HasRand,
|
||||
CS::State: HasClientPerfMonitor + HasRand + HasCorpus,
|
||||
Z: ExecutionProcessor<OT, State = CS::State>
|
||||
+ EvaluatorObservers<OT>
|
||||
+ HasScheduler<Scheduler = CS>,
|
||||
@ -59,7 +59,7 @@ where
|
||||
CS: Scheduler,
|
||||
EM: EventFirer<State = CS::State> + EventRestarter + HasEventManagerId,
|
||||
OT: ObserversTuple<CS::State>,
|
||||
CS::State: HasClientPerfMonitor + HasRand,
|
||||
CS::State: HasClientPerfMonitor + HasRand + HasCorpus,
|
||||
Z: ExecutionProcessor<OT, State = CS::State>
|
||||
+ EvaluatorObservers<OT>
|
||||
+ HasScheduler<Scheduler = CS>,
|
||||
@ -84,7 +84,7 @@ where
|
||||
CS: Scheduler,
|
||||
EM: EventFirer<State = CS::State> + EventRestarter + HasEventManagerId,
|
||||
OT: ObserversTuple<CS::State>,
|
||||
CS::State: HasClientPerfMonitor + HasRand,
|
||||
CS::State: HasClientPerfMonitor + HasRand + HasCorpus,
|
||||
Z: ExecutionProcessor<OT, State = CS::State>
|
||||
+ EvaluatorObservers<OT>
|
||||
+ HasScheduler<Scheduler = CS>,
|
||||
@ -116,7 +116,7 @@ where
|
||||
CS: Scheduler,
|
||||
EM: EventFirer<State = CS::State> + EventRestarter + HasEventManagerId,
|
||||
OT: ObserversTuple<CS::State>,
|
||||
CS::State: HasClientPerfMonitor + HasRand,
|
||||
CS::State: HasClientPerfMonitor + HasRand + HasCorpus,
|
||||
Z: ExecutionProcessor<OT, State = CS::State>
|
||||
+ EvaluatorObservers<OT>
|
||||
+ HasScheduler<Scheduler = CS>,
|
||||
@ -184,7 +184,7 @@ where
|
||||
pub trait PushStage<CS, EM, OT, Z>: Iterator
|
||||
where
|
||||
CS: Scheduler,
|
||||
CS::State: HasClientPerfMonitor + HasRand + HasExecutions + HasMetadata,
|
||||
CS::State: HasClientPerfMonitor + HasRand + HasExecutions + HasMetadata + HasCorpus,
|
||||
EM: EventFirer<State = CS::State> + EventRestarter + HasEventManagerId + ProgressReporter,
|
||||
OT: ObserversTuple<CS::State>,
|
||||
Z: ExecutionProcessor<OT, State = CS::State>
|
||||
|
@ -43,7 +43,7 @@ where
|
||||
EM: EventFirer<State = CS::State> + EventRestarter + HasEventManagerId,
|
||||
M: Mutator<CS::Input, CS::State>,
|
||||
OT: ObserversTuple<CS::State>,
|
||||
CS::State: HasClientPerfMonitor + HasRand + Clone + Debug,
|
||||
CS::State: HasClientPerfMonitor + HasRand + HasCorpus + Clone + Debug,
|
||||
Z: ExecutionProcessor<OT, State = CS::State>
|
||||
+ EvaluatorObservers<OT>
|
||||
+ HasScheduler<Scheduler = CS>,
|
||||
|
@ -192,6 +192,7 @@ where
|
||||
CS: Scheduler,
|
||||
M: Mutator<CS::Input, CS::State>,
|
||||
Z: ExecutionProcessor<OT, State = CS::State>,
|
||||
CS::State: HasCorpus,
|
||||
{
|
||||
type State = CS::State;
|
||||
}
|
||||
@ -200,7 +201,8 @@ impl<CS, E, EM, F1, F2, FF, M, OT, Z> Stage<E, EM, Z>
|
||||
for StdTMinMutationalStage<CS, E, EM, F1, F2, FF, M, OT, Z>
|
||||
where
|
||||
CS: Scheduler + RemovableScheduler,
|
||||
CS::State: HasCorpus + HasSolutions + HasExecutions + HasMaxSize + HasClientPerfMonitor,
|
||||
CS::State:
|
||||
HasCorpus + HasSolutions + HasExecutions + HasMaxSize + HasClientPerfMonitor + HasCorpus,
|
||||
<CS::State as UsesInput>::Input: HasLen + Hash,
|
||||
E: Executor<EM, Z> + HasObservers<Observers = OT, State = CS::State>,
|
||||
EM: EventFirer<State = CS::State>,
|
||||
@ -285,6 +287,7 @@ where
|
||||
CS: Scheduler,
|
||||
M: Mutator<CS::Input, CS::State>,
|
||||
Z: ExecutionProcessor<OT, State = CS::State>,
|
||||
CS::State: HasCorpus,
|
||||
{
|
||||
/// Creates a new minimising mutational stage that will minimize provided corpus entries
|
||||
pub fn new(mutator: M, factory: FF, runs: usize) -> Self {
|
||||
|
Loading…
x
Reference in New Issue
Block a user