Eco fuzz fix (#1253)
* f * more fix * aaaaa * f * fix --------- Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
This commit is contained in:
parent
721c02cd2c
commit
fe8c06dd8f
@ -42,8 +42,7 @@ pub struct EcoTestcaseMetadata {
|
|||||||
mutation_num: u64,
|
mutation_num: u64,
|
||||||
exec_num: u64,
|
exec_num: u64,
|
||||||
exec_by_mutation: u64,
|
exec_by_mutation: u64,
|
||||||
last_found: usize,
|
found: usize,
|
||||||
line: u64,
|
|
||||||
last_energy: u64,
|
last_energy: u64,
|
||||||
state: EcoState,
|
state: EcoState,
|
||||||
serial: u64,
|
serial: u64,
|
||||||
@ -60,7 +59,6 @@ pub struct EcoMetadata {
|
|||||||
last_mutation_num: u64,
|
last_mutation_num: u64,
|
||||||
last_corpus_count: usize,
|
last_corpus_count: usize,
|
||||||
last_executions: usize,
|
last_executions: usize,
|
||||||
last_find_iteration: usize,
|
|
||||||
calculate_coe: u64,
|
calculate_coe: u64,
|
||||||
rate: f64,
|
rate: f64,
|
||||||
}
|
}
|
||||||
@ -100,25 +98,24 @@ where
|
|||||||
fn handle_previous(id: CorpusId, state: &mut S) -> Result<(), Error> {
|
fn handle_previous(id: CorpusId, state: &mut S) -> Result<(), Error> {
|
||||||
let count = state.corpus().count();
|
let count = state.corpus().count();
|
||||||
|
|
||||||
let (last_mutation_num, last_corpus_count) = {
|
let (last_corpus_count, last_mutation_num) = {
|
||||||
let meta = state.metadata::<EcoMetadata>()?;
|
let m = state.metadata_mut::<EcoMetadata>()?;
|
||||||
(meta.last_mutation_num, meta.last_corpus_count)
|
(m.last_corpus_count, m.last_mutation_num)
|
||||||
};
|
};
|
||||||
|
|
||||||
let computed_score = {
|
let computed_score = {
|
||||||
let mut testcase = state.testcase_mut(id)?;
|
let mut testcase = state.testcase_mut(id)?;
|
||||||
|
|
||||||
let meta = testcase.metadata_mut::<EcoTestcaseMetadata>()?;
|
let tcmeta = testcase.metadata_mut::<EcoTestcaseMetadata>()?;
|
||||||
|
tcmeta.last_energy = tcmeta.mutation_num - last_mutation_num;
|
||||||
|
tcmeta.found = count - last_corpus_count;
|
||||||
// Set was_fuzzed for the old current
|
// Set was_fuzzed for the old current
|
||||||
meta.last_found = count - last_corpus_count;
|
tcmeta.computed_score
|
||||||
meta.last_energy = meta.mutation_num - last_mutation_num;
|
|
||||||
meta.computed_score
|
|
||||||
};
|
};
|
||||||
|
let cur_exec = *state.executions();
|
||||||
let meta = state.metadata_mut::<EcoMetadata>()?;
|
let meta = state.metadata_mut::<EcoMetadata>()?;
|
||||||
|
|
||||||
let mut regret = meta.last_find_iteration as f64 / computed_score;
|
let mut regret = (cur_exec - meta.last_executions) as f64 / computed_score;
|
||||||
if regret == 0.0 {
|
if regret == 0.0 {
|
||||||
regret = 1.1;
|
regret = 1.1;
|
||||||
}
|
}
|
||||||
@ -151,18 +148,10 @@ where
|
|||||||
|
|
||||||
/// Create a new alias table when the fuzzer finds a new corpus entry
|
/// Create a new alias table when the fuzzer finds a new corpus entry
|
||||||
fn schedule(state: &mut S) -> Result<CorpusId, Error> {
|
fn schedule(state: &mut S) -> Result<CorpusId, Error> {
|
||||||
let mut selection = None;
|
|
||||||
for id in state.corpus().ids() {
|
for id in state.corpus().ids() {
|
||||||
let was_fuzzed = state.testcase(id)?.scheduled_count() > 0;
|
let was_fuzzed = state.testcase(id)?.scheduled_count() > 0;
|
||||||
if was_fuzzed {
|
if !was_fuzzed {
|
||||||
selection = Some(id);
|
let selection = Some(id);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for id in state.corpus().ids() {
|
|
||||||
let was_fuzzed = state.testcase(id)?.scheduled_count() > 0;
|
|
||||||
if was_fuzzed {
|
|
||||||
state.metadata_mut::<EcoMetadata>()?.state = EcoState::Exploration;
|
state.metadata_mut::<EcoMetadata>()?.state = EcoState::Exploration;
|
||||||
return Ok(selection.expect("Error in the algorithm, this cannot be None"));
|
return Ok(selection.expect("Error in the algorithm, this cannot be None"));
|
||||||
}
|
}
|
||||||
@ -240,6 +229,8 @@ where
|
|||||||
None => 0,
|
None => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
assert!(self.last_hash != 0);
|
||||||
|
|
||||||
// Attach a `SchedulerTestcaseMetadata` to the queue entry.
|
// Attach a `SchedulerTestcaseMetadata` to the queue entry.
|
||||||
depth += 1;
|
depth += 1;
|
||||||
{
|
{
|
||||||
@ -255,12 +246,23 @@ where
|
|||||||
.testcase_mut(idx)?
|
.testcase_mut(idx)?
|
||||||
.add_metadata(EcoTestcaseMetadata::default());
|
.add_metadata(EcoTestcaseMetadata::default());
|
||||||
|
|
||||||
let executions = *state.executions();
|
let mut exec_num = 0;
|
||||||
let meta = state.metadata_mut::<EcoMetadata>()?;
|
for id in state.corpus().ids() {
|
||||||
|
let entry = state
|
||||||
|
.testcase(id)?
|
||||||
|
.metadata::<SchedulerTestcaseMetadata>()?
|
||||||
|
.n_fuzz_entry();
|
||||||
|
|
||||||
let last_find_iteration = executions - meta.last_executions + 1;
|
if entry == self.last_hash {
|
||||||
meta.last_find_iteration = last_find_iteration;
|
exec_num += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut tc = state.testcase_mut(idx)?;
|
||||||
|
let tcmeta = tc.metadata_mut::<EcoTestcaseMetadata>()?;
|
||||||
|
|
||||||
|
tcmeta.exec_num = exec_num;
|
||||||
|
tcmeta.serial = state.corpus().count() as u64 + 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,15 +320,10 @@ where
|
|||||||
let id = Self::schedule(state)?;
|
let id = Self::schedule(state)?;
|
||||||
self.set_current_scheduled(state, Some(id))?;
|
self.set_current_scheduled(state, Some(id))?;
|
||||||
|
|
||||||
let mutation_num = state
|
|
||||||
.testcase_mut(id)?
|
|
||||||
.metadata_mut::<EcoTestcaseMetadata>()?
|
|
||||||
.mutation_num;
|
|
||||||
let count = state.corpus().count();
|
let count = state.corpus().count();
|
||||||
let executions = *state.executions();
|
let executions = *state.executions();
|
||||||
|
|
||||||
let meta = state.metadata_mut::<EcoMetadata>()?;
|
let meta = state.metadata_mut::<EcoMetadata>()?;
|
||||||
meta.last_mutation_num = mutation_num;
|
|
||||||
meta.last_corpus_count = count;
|
meta.last_corpus_count = count;
|
||||||
// TODO in theory it should be assigned at the beginning of the mutational stage
|
// TODO in theory it should be assigned at the beginning of the mutational stage
|
||||||
// we must not count executions done in other stages
|
// we must not count executions done in other stages
|
||||||
@ -352,28 +349,37 @@ where
|
|||||||
fn compute(state: &S, entry: &mut Testcase<S::Input>) -> Result<f64, Error> {
|
fn compute(state: &S, entry: &mut Testcase<S::Input>) -> Result<f64, Error> {
|
||||||
// subtract # initial inputs to the corpus count
|
// subtract # initial inputs to the corpus count
|
||||||
let mut energy = 0;
|
let mut energy = 0;
|
||||||
let mut average_cost = (state.corpus().count() / state.executions()) as u64;
|
|
||||||
|
let (cur_state, rate, initial_corpus_count) = {
|
||||||
|
let meta = state.metadata::<EcoMetadata>()?;
|
||||||
|
(meta.state, meta.rate, meta.initial_corpus_count)
|
||||||
|
};
|
||||||
|
|
||||||
|
let initial = initial_corpus_count.unwrap_or(0);
|
||||||
|
|
||||||
|
let mut average_cost: u64 = if state.corpus().count() == initial {
|
||||||
|
*state.executions() as u64 / state.corpus().count() as u64
|
||||||
|
} else {
|
||||||
|
*state.executions() as u64 / (state.corpus().count() - initial) as u64
|
||||||
|
};
|
||||||
|
|
||||||
if average_cost == 0 {
|
if average_cost == 0 {
|
||||||
average_cost = 1024;
|
average_cost = 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (cur_state, rate) = {
|
|
||||||
let meta = state.metadata::<EcoMetadata>()?;
|
|
||||||
(meta.state, meta.rate)
|
|
||||||
};
|
|
||||||
|
|
||||||
let meta = entry.metadata_mut::<EcoTestcaseMetadata>()?;
|
let meta = entry.metadata_mut::<EcoTestcaseMetadata>()?;
|
||||||
|
|
||||||
if cur_state == EcoState::Exploitation {
|
if cur_state == EcoState::Exploitation {
|
||||||
meta.state = EcoState::Exploitation;
|
meta.state = EcoState::Exploitation;
|
||||||
if meta.last_found == 0 {
|
if meta.found == 0 {
|
||||||
energy = core::cmp::min(2 * meta.last_energy, 16 * average_cost);
|
energy = core::cmp::min(2 * meta.last_energy, 16 * average_cost);
|
||||||
} else {
|
} else {
|
||||||
energy = core::cmp::min(meta.last_energy, 16 * average_cost);
|
energy = core::cmp::min(meta.last_energy, 16 * average_cost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if energy == 0 {
|
if cur_state == EcoState::Exploitation && energy == 0 || cur_state != EcoState::Exploitation
|
||||||
|
{
|
||||||
if meta.exec_num > average_cost {
|
if meta.exec_num > average_cost {
|
||||||
energy = average_cost / 4;
|
energy = average_cost / 4;
|
||||||
} else if meta.exec_num > average_cost / 2 {
|
} else if meta.exec_num > average_cost / 2 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user