on crash callback in inmem executor
This commit is contained in:
parent
fde6201d74
commit
cf7c9cd571
@ -33,12 +33,11 @@ pub trait StateMetadata: Debug {
|
|||||||
/// The state a fuzz run.
|
/// The state a fuzz run.
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
#[serde(bound = "FT: serde::de::DeserializeOwned")]
|
#[serde(bound = "FT: serde::de::DeserializeOwned")]
|
||||||
pub struct State<I, R, FT, OT>
|
pub struct State<I, R, FT>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
OT: ObserversTuple,
|
|
||||||
{
|
{
|
||||||
/// How many times the executor ran the harness/target
|
/// How many times the executor ran the harness/target
|
||||||
executions: usize,
|
executions: usize,
|
||||||
@ -49,17 +48,16 @@ where
|
|||||||
// additional_corpuses, maybe another TupleList?
|
// additional_corpuses, maybe another TupleList?
|
||||||
// Feedbacks used to evaluate an input
|
// Feedbacks used to evaluate an input
|
||||||
feedbacks: FT,
|
feedbacks: FT,
|
||||||
phantom: PhantomData<(I, R, OT)>,
|
phantom: PhantomData<(I, R)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<R, FT, OT> State<BytesInput, R, FT, OT>
|
impl<R, FT> State<BytesInput, R, FT>
|
||||||
where
|
where
|
||||||
R: Rand,
|
R: Rand,
|
||||||
FT: FeedbacksTuple<BytesInput>,
|
FT: FeedbacksTuple<BytesInput>,
|
||||||
OT: ObserversTuple,
|
|
||||||
{
|
{
|
||||||
pub fn load_from_directory<G, C, E, ET, EM>(
|
pub fn load_from_directory<G, C, E, OT, ET, EM>(
|
||||||
&mut self,
|
&mut self,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
@ -71,8 +69,9 @@ where
|
|||||||
G: Generator<BytesInput, R>,
|
G: Generator<BytesInput, R>,
|
||||||
C: Corpus<BytesInput, R>,
|
C: Corpus<BytesInput, R>,
|
||||||
E: Executor<BytesInput> + HasObservers<OT>,
|
E: Executor<BytesInput> + HasObservers<OT>,
|
||||||
|
OT: ObserversTuple,
|
||||||
ET: ExecutorsTuple<BytesInput>,
|
ET: ExecutorsTuple<BytesInput>,
|
||||||
EM: EventManager<C, E, OT, FT, BytesInput, R>,
|
EM: EventManager<C, E, FT, BytesInput, R>,
|
||||||
{
|
{
|
||||||
for entry in fs::read_dir(in_dir)? {
|
for entry in fs::read_dir(in_dir)? {
|
||||||
let entry = entry?;
|
let entry = entry?;
|
||||||
@ -101,7 +100,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_initial_inputs<G, C, E, ET, EM>(
|
pub fn load_initial_inputs<G, C, E, OT, ET, EM>(
|
||||||
&mut self,
|
&mut self,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
@ -113,8 +112,9 @@ where
|
|||||||
G: Generator<BytesInput, R>,
|
G: Generator<BytesInput, R>,
|
||||||
C: Corpus<BytesInput, R>,
|
C: Corpus<BytesInput, R>,
|
||||||
E: Executor<BytesInput> + HasObservers<OT>,
|
E: Executor<BytesInput> + HasObservers<OT>,
|
||||||
|
OT: ObserversTuple,
|
||||||
ET: ExecutorsTuple<BytesInput>,
|
ET: ExecutorsTuple<BytesInput>,
|
||||||
EM: EventManager<C, E, OT, FT, BytesInput, R>,
|
EM: EventManager<C, E, FT, BytesInput, R>,
|
||||||
{
|
{
|
||||||
for in_dir in in_dirs {
|
for in_dir in in_dirs {
|
||||||
self.load_from_directory(corpus, generator, engine, manager, in_dir)?;
|
self.load_from_directory(corpus, generator, engine, manager, in_dir)?;
|
||||||
@ -128,12 +128,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, FT, OT> State<I, R, FT, OT>
|
impl<I, R, FT> State<I, R, FT>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
OT: ObserversTuple,
|
|
||||||
{
|
{
|
||||||
/// Get executions
|
/// Get executions
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -206,7 +205,7 @@ where
|
|||||||
|
|
||||||
// TODO move some of these, like evaluate_input, to FuzzingEngine
|
// TODO move some of these, like evaluate_input, to FuzzingEngine
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_interesting(&mut self, input: &I, observers: &OT) -> Result<u32, AflError>
|
pub fn is_interesting<OT>(&mut self, input: &I, observers: &OT) -> Result<u32, AflError>
|
||||||
where
|
where
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
{
|
{
|
||||||
@ -214,9 +213,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Runs the input and triggers observers and feedback
|
/// Runs the input and triggers observers and feedback
|
||||||
pub fn evaluate_input<E>(&mut self, input: &I, executor: &mut E) -> Result<u32, AflError>
|
pub fn evaluate_input<E, OT>(&mut self, input: &I, executor: &mut E) -> Result<u32, AflError>
|
||||||
where
|
where
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
|
OT: ObserversTuple,
|
||||||
{
|
{
|
||||||
executor.reset_observers()?;
|
executor.reset_observers()?;
|
||||||
executor.run_target(&input)?;
|
executor.run_target(&input)?;
|
||||||
@ -279,7 +279,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_initial_inputs<G, C, E, ET, EM>(
|
pub fn generate_initial_inputs<G, C, E, OT, ET, EM>(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
@ -292,8 +292,9 @@ where
|
|||||||
G: Generator<I, R>,
|
G: Generator<I, R>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
|
OT: ObserversTuple,
|
||||||
ET: ExecutorsTuple<I>,
|
ET: ExecutorsTuple<I>,
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
{
|
{
|
||||||
let mut added = 0;
|
let mut added = 0;
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
@ -383,7 +384,7 @@ where
|
|||||||
pub trait Fuzzer<ST, EM, E, OT, FT, ET, C, I, R>
|
pub trait Fuzzer<ST, EM, E, OT, FT, ET, C, I, R>
|
||||||
where
|
where
|
||||||
ST: StagesTuple<EM, E, OT, FT, ET, C, I, R>,
|
ST: StagesTuple<EM, E, OT, FT, ET, C, I, R>,
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -399,7 +400,7 @@ where
|
|||||||
fn fuzz_one(
|
fn fuzz_one(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<I, R, FT, OT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<E, OT, ET, I>,
|
engine: &mut Engine<E, OT, ET, I>,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
@ -416,7 +417,7 @@ where
|
|||||||
fn fuzz_loop(
|
fn fuzz_loop(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<I, R, FT, OT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<E, OT, ET, I>,
|
engine: &mut Engine<E, OT, ET, I>,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
@ -437,7 +438,7 @@ where
|
|||||||
pub struct StdFuzzer<ST, EM, E, OT, FT, ET, C, I, R>
|
pub struct StdFuzzer<ST, EM, E, OT, FT, ET, C, I, R>
|
||||||
where
|
where
|
||||||
ST: StagesTuple<EM, E, OT, FT, ET, C, I, R>,
|
ST: StagesTuple<EM, E, OT, FT, ET, C, I, R>,
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -454,7 +455,7 @@ impl<ST, EM, E, OT, FT, ET, C, I, R> Fuzzer<ST, EM, E, OT, FT, ET, C, I, R>
|
|||||||
for StdFuzzer<ST, EM, E, OT, FT, ET, C, I, R>
|
for StdFuzzer<ST, EM, E, OT, FT, ET, C, I, R>
|
||||||
where
|
where
|
||||||
ST: StagesTuple<EM, E, OT, FT, ET, C, I, R>,
|
ST: StagesTuple<EM, E, OT, FT, ET, C, I, R>,
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -475,7 +476,7 @@ where
|
|||||||
impl<ST, EM, E, OT, FT, ET, C, I, R> StdFuzzer<ST, EM, E, OT, FT, ET, C, I, R>
|
impl<ST, EM, E, OT, FT, ET, C, I, R> StdFuzzer<ST, EM, E, OT, FT, ET, C, I, R>
|
||||||
where
|
where
|
||||||
ST: StagesTuple<EM, E, OT, FT, ET, C, I, R>,
|
ST: StagesTuple<EM, E, OT, FT, ET, C, I, R>,
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
|
@ -211,23 +211,21 @@ where
|
|||||||
where
|
where
|
||||||
ST: Stats;
|
ST: Stats;
|
||||||
/// This method will be called in the clients after handle_in_broker (unless BrokerEventResult::Handled) was returned in handle_in_broker
|
/// This method will be called in the clients after handle_in_broker (unless BrokerEventResult::Handled) was returned in handle_in_broker
|
||||||
fn handle_in_client<C, OT, FT, R>(
|
fn handle_in_client<C, FT, R>(
|
||||||
self,
|
self,
|
||||||
state: &mut State<I, R, FT, OT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
) -> Result<(), AflError>
|
) -> Result<(), AflError>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
OT: ObserversTuple,
|
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
R: Rand;
|
R: Rand;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait EventManager<C, E, OT, FT, I, R>
|
pub trait EventManager<C, E, FT, I, R>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
OT: ObserversTuple,
|
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -239,25 +237,25 @@ where
|
|||||||
/// Return the number of processes events or an error
|
/// Return the number of processes events or an error
|
||||||
fn process(
|
fn process(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut State<I, R, FT, OT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
) -> Result<usize, AflError>;
|
) -> Result<usize, AflError>;
|
||||||
|
|
||||||
fn serialize_observers(&mut self, observers: &OT) -> Result<Vec<u8>, AflError> {
|
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Vec<u8>, AflError> where OT: ObserversTuple {
|
||||||
Ok(postcard::to_allocvec(observers)?)
|
Ok(postcard::to_allocvec(observers)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_observers(&mut self, observers_buf: &[u8]) -> Result<OT, AflError> {
|
fn deserialize_observers<OT>(&mut self, observers_buf: &[u8]) -> Result<OT, AflError> where OT: ObserversTuple {
|
||||||
Ok(postcard::from_bytes(observers_buf)?)
|
Ok(postcard::from_bytes(observers_buf)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_testcase(
|
fn new_testcase<OT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_input: &I,
|
_input: &I,
|
||||||
_observers: &OT,
|
_observers: &OT,
|
||||||
_corpus_size: usize,
|
_corpus_size: usize,
|
||||||
_config: String,
|
_config: String,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> where OT: ObserversTuple {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,14 +382,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn handle_in_client<C, OT, FT, R>(
|
fn handle_in_client<C, FT, R>(
|
||||||
self,
|
self,
|
||||||
_state: &mut State<I, R, FT, OT>,
|
_state: &mut State<I, R, FT>,
|
||||||
_corpus: &mut C,
|
_corpus: &mut C,
|
||||||
) -> Result<(), AflError>
|
) -> Result<(), AflError>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
OT: ObserversTuple,
|
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
@ -405,11 +402,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LoggerEventManager<C, E, OT, FT, I, R, ST>
|
pub struct LoggerEventManager<C, E, FT, I, R, ST>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
OT: ObserversTuple,
|
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -419,15 +415,14 @@ where
|
|||||||
stats: ST,
|
stats: ST,
|
||||||
events: Vec<LoggerEvent<I>>,
|
events: Vec<LoggerEvent<I>>,
|
||||||
// stats (maybe we need a separated struct?)
|
// stats (maybe we need a separated struct?)
|
||||||
phantom: PhantomData<(C, E, I, R, OT, FT)>,
|
phantom: PhantomData<(C, E, I, R, FT)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, OT, FT, I, R, ST> EventManager<C, E, OT, FT, I, R>
|
impl<C, E, FT, I, R, ST> EventManager<C, E, FT, I, R>
|
||||||
for LoggerEventManager<C, E, OT, FT, I, R, ST>
|
for LoggerEventManager<C, E, FT, I, R, ST>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
OT: ObserversTuple,
|
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -436,7 +431,7 @@ where
|
|||||||
{
|
{
|
||||||
fn process(
|
fn process(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut State<I, R, FT, OT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
) -> Result<usize, AflError> {
|
) -> Result<usize, AflError> {
|
||||||
let count = self.events.len();
|
let count = self.events.len();
|
||||||
@ -446,13 +441,13 @@ where
|
|||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_testcase(
|
fn new_testcase<OT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_input: &I,
|
_input: &I,
|
||||||
_observers: &OT,
|
_observers: &OT,
|
||||||
corpus_size: usize,
|
corpus_size: usize,
|
||||||
_config: String,
|
_config: String,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> where OT: ObserversTuple {
|
||||||
let event = LoggerEvent::NewTestcase {
|
let event = LoggerEvent::NewTestcase {
|
||||||
corpus_size: corpus_size,
|
corpus_size: corpus_size,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
@ -513,12 +508,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, OT, FT, I, R, ST> LoggerEventManager<C, E, OT, FT, I, R, ST>
|
impl<C, E, FT, I, R, ST> LoggerEventManager<C, E, FT, I, R, ST>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
OT: ObserversTuple,
|
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
ST: Stats,
|
ST: Stats,
|
||||||
@ -658,14 +652,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn handle_in_client<C, OT, FT, R>(
|
fn handle_in_client<C, FT, R>(
|
||||||
self,
|
self,
|
||||||
state: &mut State<I, R, FT, OT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
) -> Result<(), AflError>
|
) -> Result<(), AflError>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
OT: ObserversTuple,
|
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
@ -706,11 +699,10 @@ const _LLMP_TAG_EVENT_TO_BROKER: llmp::Tag = 0x2B80438;
|
|||||||
const LLMP_TAG_EVENT_TO_BOTH: llmp::Tag = 0x2B0741;
|
const LLMP_TAG_EVENT_TO_BOTH: llmp::Tag = 0x2B0741;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LlmpEventManager<C, E, OT, FT, I, R, SH, ST>
|
pub struct LlmpEventManager<C, E, FT, I, R, SH, ST>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
OT: ObserversTuple,
|
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -720,15 +712,14 @@ where
|
|||||||
{
|
{
|
||||||
llmp: llmp::LlmpConnection<SH>,
|
llmp: llmp::LlmpConnection<SH>,
|
||||||
stats: ST,
|
stats: ST,
|
||||||
phantom: PhantomData<(C, E, OT, FT, I, R)>,
|
phantom: PhantomData<(C, E, FT, I, R)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<C, E, OT, FT, I, R, ST> LlmpEventManager<C, E, OT, FT, I, R, AflShmem, ST>
|
impl<C, E, FT, I, R, ST> LlmpEventManager<C, E, FT, I, R, AflShmem, ST>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
OT: ObserversTuple,
|
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -754,11 +745,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, OT, FT, I, R, SH, ST> LlmpEventManager<C, E, OT, FT, I, R, SH, ST>
|
impl<C, E, FT, I, R, SH, ST> LlmpEventManager<C, E, FT, I, R, SH, ST>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
OT: ObserversTuple,
|
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -859,13 +849,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, OT, FT, I, R, SH, ST> EventManager<C, E, OT, FT, I, R>
|
impl<C, E, FT, I, R, SH, ST> EventManager<C, E, FT, I, R>
|
||||||
for LlmpEventManager<C, E, OT, FT, I, R, SH, ST>
|
for LlmpEventManager<C, E, FT, I, R, SH, ST>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
OT: ObserversTuple,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
SH: ShMem,
|
SH: ShMem,
|
||||||
@ -874,7 +863,7 @@ where
|
|||||||
{
|
{
|
||||||
fn process(
|
fn process(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut State<I, R, FT, OT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
) -> Result<usize, AflError> {
|
) -> Result<usize, AflError> {
|
||||||
// TODO: Get around local event copy by moving handle_in_client
|
// TODO: Get around local event copy by moving handle_in_client
|
||||||
@ -907,13 +896,13 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_testcase(
|
fn new_testcase<OT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
input: &I,
|
input: &I,
|
||||||
observers: &OT,
|
observers: &OT,
|
||||||
corpus_size: usize,
|
corpus_size: usize,
|
||||||
config: String,
|
config: String,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> where OT: ObserversTuple {
|
||||||
let kind = LLMPEventKind::NewTestcase {
|
let kind = LLMPEventKind::NewTestcase {
|
||||||
input: Ptr::Ref(input),
|
input: Ptr::Ref(input),
|
||||||
observers_buf: postcard::to_allocvec(observers)?,
|
observers_buf: postcard::to_allocvec(observers)?,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use alloc::{boxed::Box, string::ToString, vec::Vec};
|
use alloc::{boxed::Box, string::ToString, vec::Vec};
|
||||||
use core::{ffi::c_void, ptr};
|
use core::{marker::PhantomData, ffi::c_void, ptr};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
@ -20,16 +20,26 @@ use self::unix_signals::setup_crash_handlers;
|
|||||||
/// The (unsafe) pointer to the current inmem input, for the current run.
|
/// The (unsafe) pointer to the current inmem input, for the current run.
|
||||||
/// This is neede for certain non-rust side effects, as well as unix signal handling.
|
/// This is neede for certain non-rust side effects, as well as unix signal handling.
|
||||||
static mut CURRENT_INPUT_PTR: *const c_void = ptr::null();
|
static mut CURRENT_INPUT_PTR: *const c_void = ptr::null();
|
||||||
static mut CURRENT_ON_CRASH_FN: *mut Box<dyn FnMut(ExitKind, &[u8])> = ptr::null_mut();
|
static mut CURRENT_ON_CRASH_FN: *mut c_void = ptr::null_mut();
|
||||||
|
|
||||||
|
static mut CORPUS_PTR: *const c_void = ptr::null_mut();
|
||||||
|
static mut STATE_PTR: *const c_void = ptr::null_mut();
|
||||||
|
static mut EVENT_MANAGER_PTR: *mut c_void = ptr::null_mut();
|
||||||
|
|
||||||
/// The inmem executor harness
|
/// The inmem executor harness
|
||||||
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
|
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
|
||||||
|
type OnCrashFunction<I, C, EM, FT, R> = fn(ExitKind, &State<I, R, FT>, &C, &mut EM);
|
||||||
|
|
||||||
/// The inmem executor simply calls a target function, then returns afterwards.
|
/// The inmem executor simply calls a target function, then returns afterwards.
|
||||||
pub struct InMemoryExecutor<I, OT>
|
pub struct InMemoryExecutor<I, OT, C, E, EM, FT, R>
|
||||||
where
|
where
|
||||||
I: Input + HasTargetBytes,
|
I: Input + HasTargetBytes,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
E: Executor<I>,
|
||||||
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
R: Rand,
|
||||||
{
|
{
|
||||||
/// The name of this executor instance, to address it from other components
|
/// The name of this executor instance, to address it from other components
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
@ -38,19 +48,26 @@ where
|
|||||||
/// The observers, observing each run
|
/// The observers, observing each run
|
||||||
observers: OT,
|
observers: OT,
|
||||||
/// A special function being called right before the process crashes. It may save state to restore fuzzing after respawn.
|
/// A special function being called right before the process crashes. It may save state to restore fuzzing after respawn.
|
||||||
on_crash_fn: Box<dyn FnMut(ExitKind, &[u8])>,
|
on_crash_fn: OnCrashFunction<I, C, EM, FT, R>,
|
||||||
|
|
||||||
|
phantom: PhantomData<E>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, OT> Executor<I> for InMemoryExecutor<I, OT>
|
impl<I, OT, C, E, EM, FT, R> Executor<I> for InMemoryExecutor<I, OT, C, E, EM, FT, R>
|
||||||
where
|
where
|
||||||
I: Input + HasTargetBytes,
|
I: Input + HasTargetBytes,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
E: Executor<I>,
|
||||||
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
R: Rand,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError> {
|
fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError> {
|
||||||
let bytes = input.target_bytes();
|
let bytes = input.target_bytes();
|
||||||
unsafe {
|
unsafe {
|
||||||
CURRENT_ON_CRASH_FN = &mut self.on_crash_fn as *mut _;
|
CURRENT_ON_CRASH_FN = &mut self.on_crash_fn as *mut _ as *mut c_void;
|
||||||
CURRENT_INPUT_PTR = input as *const _ as *const c_void;
|
CURRENT_INPUT_PTR = input as *const _ as *const c_void;
|
||||||
}
|
}
|
||||||
let ret = (self.harness)(self, bytes.as_slice());
|
let ret = (self.harness)(self, bytes.as_slice());
|
||||||
@ -62,20 +79,30 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, OT> Named for InMemoryExecutor<I, OT>
|
impl<I, OT, C, E, EM, FT, R> Named for InMemoryExecutor<I, OT, C, E, EM, FT, R>
|
||||||
where
|
where
|
||||||
I: Input + HasTargetBytes,
|
I: Input + HasTargetBytes,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
E: Executor<I>,
|
||||||
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
R: Rand,
|
||||||
{
|
{
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
self.name
|
self.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, OT> HasObservers<OT> for InMemoryExecutor<I, OT>
|
impl<I, OT, C, E, EM, FT, R> HasObservers<OT> for InMemoryExecutor<I, OT, C, E, EM, FT, R>
|
||||||
where
|
where
|
||||||
I: Input + HasTargetBytes,
|
I: Input + HasTargetBytes,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
E: Executor<I>,
|
||||||
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
R: Rand,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn observers(&self) -> &OT {
|
fn observers(&self) -> &OT {
|
||||||
@ -88,10 +115,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, OT> InMemoryExecutor<I, OT>
|
impl<I, OT, C, E, EM, FT, R> InMemoryExecutor<I, OT, C, E, EM, FT, R>
|
||||||
where
|
where
|
||||||
I: Input + HasTargetBytes,
|
I: Input + HasTargetBytes,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
E: Executor<I>,
|
||||||
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
R: Rand,
|
||||||
{
|
{
|
||||||
/// Create a new in mem executor.
|
/// Create a new in mem executor.
|
||||||
/// Caution: crash and restart in one of them will lead to odd behavior if multiple are used,
|
/// Caution: crash and restart in one of them will lead to odd behavior if multiple are used,
|
||||||
@ -101,42 +133,31 @@ where
|
|||||||
/// * `on_crash_fn` - When an in-mem harness crashes, it may safe some state to continue fuzzing later.
|
/// * `on_crash_fn` - When an in-mem harness crashes, it may safe some state to continue fuzzing later.
|
||||||
/// Do that that in this function. The program will crash afterwards.
|
/// Do that that in this function. The program will crash afterwards.
|
||||||
/// * `observers` - the observers observing the target during execution
|
/// * `observers` - the observers observing the target during execution
|
||||||
pub fn new<C, E, EM, FT, R>(
|
pub fn new(
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
harness_fn: HarnessFunction<I>,
|
harness_fn: HarnessFunction<I>,
|
||||||
observers: OT,
|
observers: OT,
|
||||||
on_crash_fn: Box<dyn FnMut(ExitKind, &[u8])>,
|
on_crash_fn: OnCrashFunction<I, C, EM, FT, R>,
|
||||||
_state: &State<I, R, FT, OT>,
|
|
||||||
_corpus: &C,
|
|
||||||
_event_manager: &mut EM,
|
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
|
||||||
C: Corpus<I, R>,
|
|
||||||
E: Executor<I>,
|
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
|
||||||
FT: FeedbacksTuple<I>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
#[cfg(feature = "std")]
|
/*#[cfg(feature = "std")]
|
||||||
unsafe {
|
unsafe {
|
||||||
CORPUS_PTR = _corpus as *const _ as *const c_void;
|
CORPUS_PTR = _corpus as *const _ as *const c_void;
|
||||||
STATE_PTR = _state as *const _ as *const c_void;
|
STATE_PTR = _state as *const _ as *const c_void;
|
||||||
|
|
||||||
setup_crash_handlers(_event_manager);
|
setup_crash_handlers(_event_manager);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
harness: harness_fn,
|
harness: harness_fn,
|
||||||
on_crash_fn,
|
on_crash_fn,
|
||||||
observers,
|
observers,
|
||||||
name,
|
name,
|
||||||
|
phantom: PhantomData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut CORPUS_PTR: *const c_void = ptr::null_mut();
|
|
||||||
static mut STATE_PTR: *const c_void = ptr::null_mut();
|
|
||||||
|
|
||||||
/// Serialize the current state and corpus during an executiont to bytes.
|
/// Serialize the current state and corpus during an executiont to bytes.
|
||||||
/// This method is needed when the fuzzer run crashes and has to restart.
|
/// This method is needed when the fuzzer run crashes and has to restart.
|
||||||
pub unsafe fn serialize_state_corpus<C, FT, I, OT, R>() -> Result<Vec<u8>, AflError>
|
pub unsafe fn serialize_state_corpus<C, FT, I, OT, R>() -> Result<Vec<u8>, AflError>
|
||||||
@ -153,7 +174,7 @@ where
|
|||||||
.to_string(),
|
.to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let state: &State<I, R, FT, OT> = (STATE_PTR as *const State<I, R, FT, OT>).as_ref().unwrap();
|
let state: &State<I, R, FT> = (STATE_PTR as *const State<I, R, FT>).as_ref().unwrap();
|
||||||
let corpus = (CORPUS_PTR as *mut C).as_ref().unwrap();
|
let corpus = (CORPUS_PTR as *mut C).as_ref().unwrap();
|
||||||
let state_bytes = postcard::to_allocvec(&state)?;
|
let state_bytes = postcard::to_allocvec(&state)?;
|
||||||
let corpus_bytes = postcard::to_allocvec(&corpus)?;
|
let corpus_bytes = postcard::to_allocvec(&corpus)?;
|
||||||
@ -163,7 +184,7 @@ where
|
|||||||
/// Deserialize the state and corpus tuple, previously serialized with `serialize_state_corpus(...)`
|
/// Deserialize the state and corpus tuple, previously serialized with `serialize_state_corpus(...)`
|
||||||
pub fn deserialize_state_corpus<C, FT, I, OT, R>(
|
pub fn deserialize_state_corpus<C, FT, I, OT, R>(
|
||||||
state_corpus_serialized: &[u8],
|
state_corpus_serialized: &[u8],
|
||||||
) -> Result<(State<I, R, FT, OT>, C), AflError>
|
) -> Result<(State<I, R, FT>, C), AflError>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -201,23 +222,22 @@ pub mod unix_signals {
|
|||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
events::EventManager,
|
events::EventManager,
|
||||||
executors::{
|
executors::{
|
||||||
inmemory::{serialize_state_corpus, ExitKind, CURRENT_INPUT_PTR, CURRENT_ON_CRASH_FN},
|
inmemory::{OnCrashFunction, ExitKind, CURRENT_INPUT_PTR, CURRENT_ON_CRASH_FN, CORPUS_PTR, STATE_PTR, EVENT_MANAGER_PTR},
|
||||||
Executor,
|
Executor,
|
||||||
},
|
},
|
||||||
|
engines::State,
|
||||||
feedbacks::FeedbacksTuple,
|
feedbacks::FeedbacksTuple,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
utils::Rand,
|
utils::Rand,
|
||||||
};
|
};
|
||||||
|
|
||||||
static mut EVENT_MANAGER_PTR: *mut c_void = ptr::null_mut();
|
|
||||||
|
|
||||||
pub unsafe extern "C" fn libaflrs_executor_inmem_handle_crash<EM, C, E, OT, FT, I, R>(
|
pub unsafe extern "C" fn libaflrs_executor_inmem_handle_crash<EM, C, E, OT, FT, I, R>(
|
||||||
_sig: c_int,
|
_sig: c_int,
|
||||||
info: siginfo_t,
|
info: siginfo_t,
|
||||||
_void: c_void,
|
_void: c_void,
|
||||||
) where
|
) where
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
@ -238,14 +258,18 @@ pub mod unix_signals {
|
|||||||
let _ = stdout().flush();
|
let _ = stdout().flush();
|
||||||
|
|
||||||
let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap();
|
let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap();
|
||||||
|
let corpus = (CORPUS_PTR as *const C).as_ref().unwrap();
|
||||||
|
let state = (EVENT_MANAGER_PTR as *const State<I, R, FT>).as_ref().unwrap();
|
||||||
let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap();
|
let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap();
|
||||||
|
|
||||||
manager.crash(input).expect("Error in sending Crash event");
|
manager.crash(input).expect("Error in sending Crash event");
|
||||||
|
|
||||||
if !CURRENT_ON_CRASH_FN.is_null() {
|
if !CURRENT_ON_CRASH_FN.is_null() {
|
||||||
(*CURRENT_ON_CRASH_FN)(
|
(*(CURRENT_ON_CRASH_FN as *mut OnCrashFunction<I, C, EM, FT, R>))(
|
||||||
ExitKind::Crash,
|
ExitKind::Crash,
|
||||||
&serialize_state_corpus::<C, FT, I, OT, R>().unwrap(),
|
state,
|
||||||
|
corpus,
|
||||||
|
manager
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +281,7 @@ pub mod unix_signals {
|
|||||||
_info: siginfo_t,
|
_info: siginfo_t,
|
||||||
_void: c_void,
|
_void: c_void,
|
||||||
) where
|
) where
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
@ -272,6 +296,8 @@ pub mod unix_signals {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap();
|
let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap();
|
||||||
|
let corpus = (CORPUS_PTR as *const C).as_ref().unwrap();
|
||||||
|
let state = (EVENT_MANAGER_PTR as *const State<I, R, FT>).as_ref().unwrap();
|
||||||
let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap();
|
let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap();
|
||||||
|
|
||||||
manager
|
manager
|
||||||
@ -279,9 +305,11 @@ pub mod unix_signals {
|
|||||||
.expect("Error in sending Timeout event");
|
.expect("Error in sending Timeout event");
|
||||||
|
|
||||||
if !CURRENT_ON_CRASH_FN.is_null() {
|
if !CURRENT_ON_CRASH_FN.is_null() {
|
||||||
(*CURRENT_ON_CRASH_FN)(
|
(*(CURRENT_ON_CRASH_FN as *mut OnCrashFunction<I, C, EM, FT, R>))(
|
||||||
ExitKind::Timeout,
|
ExitKind::Timeout,
|
||||||
&serialize_state_corpus::<C, FT, I, OT, R>().unwrap(),
|
state,
|
||||||
|
corpus,
|
||||||
|
manager
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,9 +320,9 @@ pub mod unix_signals {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO clearly state that manager should be static (maybe put the 'static lifetime?)
|
// TODO clearly state that manager should be static (maybe put the 'static lifetime?)
|
||||||
pub unsafe fn setup_crash_handlers<EM, C, E, OT, FT, I, R>(manager: &mut EM)
|
pub unsafe fn setup_crash_handlers<EM, C, E, OT, FT, I, R>(state: &State<I, R, FT>, corpus: &C, manager: &mut EM)
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
@ -302,6 +330,8 @@ pub mod unix_signals {
|
|||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
|
CORPUS_PTR = corpus as *const _ as *const c_void;
|
||||||
|
STATE_PTR = state as *const _ as *const c_void;
|
||||||
EVENT_MANAGER_PTR = manager as *mut _ as *mut c_void;
|
EVENT_MANAGER_PTR = manager as *mut _ as *mut c_void;
|
||||||
|
|
||||||
let mut sa: sigaction = mem::zeroed();
|
let mut sa: sigaction = mem::zeroed();
|
||||||
|
@ -16,7 +16,7 @@ use crate::AflError;
|
|||||||
/// Multiple stages will be scheduled one by one for each input.
|
/// Multiple stages will be scheduled one by one for each input.
|
||||||
pub trait Stage<EM, E, OT, FT, ET, C, I, R>
|
pub trait Stage<EM, E, OT, FT, ET, C, I, R>
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -29,7 +29,7 @@ where
|
|||||||
fn perform(
|
fn perform(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<I, R, FT, OT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<E, OT, ET, I>,
|
engine: &mut Engine<E, OT, ET, I>,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
@ -39,7 +39,7 @@ where
|
|||||||
|
|
||||||
pub trait StagesTuple<EM, E, OT, FT, ET, C, I, R>
|
pub trait StagesTuple<EM, E, OT, FT, ET, C, I, R>
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -51,7 +51,7 @@ where
|
|||||||
fn perform_all(
|
fn perform_all(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<I, R, FT, OT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<E, OT, ET, I>,
|
engine: &mut Engine<E, OT, ET, I>,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
@ -63,7 +63,7 @@ where
|
|||||||
|
|
||||||
impl<EM, E, OT, FT, ET, C, I, R> StagesTuple<EM, E, OT, FT, ET, C, I, R> for ()
|
impl<EM, E, OT, FT, ET, C, I, R> StagesTuple<EM, E, OT, FT, ET, C, I, R> for ()
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -75,7 +75,7 @@ where
|
|||||||
fn perform_all(
|
fn perform_all(
|
||||||
&mut self,
|
&mut self,
|
||||||
_rand: &mut R,
|
_rand: &mut R,
|
||||||
_state: &mut State<I, R, FT, OT>,
|
_state: &mut State<I, R, FT>,
|
||||||
_corpus: &mut C,
|
_corpus: &mut C,
|
||||||
_engine: &mut Engine<E, OT, ET, I>,
|
_engine: &mut Engine<E, OT, ET, I>,
|
||||||
_manager: &mut EM,
|
_manager: &mut EM,
|
||||||
@ -92,7 +92,7 @@ impl<Head, Tail, EM, E, OT, FT, ET, C, I, R> StagesTuple<EM, E, OT, FT, ET, C, I
|
|||||||
where
|
where
|
||||||
Head: Stage<EM, E, OT, FT, ET, C, I, R>,
|
Head: Stage<EM, E, OT, FT, ET, C, I, R>,
|
||||||
Tail: StagesTuple<EM, E, OT, FT, ET, C, I, R> + TupleList,
|
Tail: StagesTuple<EM, E, OT, FT, ET, C, I, R> + TupleList,
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -104,7 +104,7 @@ where
|
|||||||
fn perform_all(
|
fn perform_all(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<I, R, FT, OT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<E, OT, ET, I>,
|
engine: &mut Engine<E, OT, ET, I>,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
|
@ -21,7 +21,7 @@ pub trait MutationalStage<M, EM, E, OT, FT, ET, C, I, R>:
|
|||||||
Stage<EM, E, OT, FT, ET, C, I, R>
|
Stage<EM, E, OT, FT, ET, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -47,7 +47,7 @@ where
|
|||||||
fn perform_mutational(
|
fn perform_mutational(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<I, R, FT, OT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<E, OT, ET, I>,
|
engine: &mut Engine<E, OT, ET, I>,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
@ -89,7 +89,7 @@ where
|
|||||||
pub struct StdMutationalStage<M, EM, E, OT, FT, ET, C, I, R>
|
pub struct StdMutationalStage<M, EM, E, OT, FT, ET, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -106,7 +106,7 @@ impl<M, EM, E, OT, FT, ET, C, I, R> MutationalStage<M, EM, E, OT, FT, ET, C, I,
|
|||||||
for StdMutationalStage<M, EM, E, OT, FT, ET, C, I, R>
|
for StdMutationalStage<M, EM, E, OT, FT, ET, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -132,7 +132,7 @@ impl<M, EM, E, OT, FT, ET, C, I, R> Stage<EM, E, OT, FT, ET, C, I, R>
|
|||||||
for StdMutationalStage<M, EM, E, OT, FT, ET, C, I, R>
|
for StdMutationalStage<M, EM, E, OT, FT, ET, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -145,7 +145,7 @@ where
|
|||||||
fn perform(
|
fn perform(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<I, R, FT, OT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<E, OT, ET, I>,
|
engine: &mut Engine<E, OT, ET, I>,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
@ -158,7 +158,7 @@ where
|
|||||||
impl<M, EM, E, OT, FT, ET, C, I, R> StdMutationalStage<M, EM, E, OT, FT, ET, C, I, R>
|
impl<M, EM, E, OT, FT, ET, C, I, R> StdMutationalStage<M, EM, E, OT, FT, ET, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
EM: EventManager<C, E, OT, FT, I, R>,
|
EM: EventManager<C, E, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user