Add back executions to Testcase (#3115)

* Add back executions to Testcase

* Small clippy

---------

Co-authored-by: Dongjia "toka" Zhang <tokazerkje@outlook.com>
This commit is contained in:
lazymio 2025-04-03 23:24:38 +08:00 committed by GitHub
parent c99371fd20
commit 0fdfa1d7a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 36 additions and 0 deletions

View File

@ -407,6 +407,7 @@ impl<I> InMemoryOnDiskCorpus<I> {
let ondisk_meta = OnDiskMetadata { let ondisk_meta = OnDiskMetadata {
metadata: testcase.metadata_map(), metadata: testcase.metadata_map(),
exec_time: testcase.exec_time(), exec_time: testcase.exec_time(),
executions: testcase.executions(),
}; };
let mut tmpfile = File::create(&tmpfile_path)?; let mut tmpfile = File::create(&tmpfile_path)?;

View File

@ -43,6 +43,8 @@ pub struct OnDiskMetadata<'a> {
pub metadata: &'a SerdeAnyMap, pub metadata: &'a SerdeAnyMap,
/// The exec time for this [`Testcase`] /// The exec time for this [`Testcase`]
pub exec_time: &'a Option<Duration>, pub exec_time: &'a Option<Duration>,
/// The executions of this [`Testcase`]
pub executions: &'a u64,
} }
/// A corpus able to store [`Testcase`]s to disk, and load them from disk, when they are being used. /// A corpus able to store [`Testcase`]s to disk, and load them from disk, when they are being used.

View File

@ -50,6 +50,8 @@ pub struct Testcase<I> {
cached_len: Option<usize>, cached_len: Option<usize>,
/// Number of fuzzing iterations of this particular input updated in `perform_mutational` /// Number of fuzzing iterations of this particular input updated in `perform_mutational`
scheduled_count: usize, scheduled_count: usize,
/// Number of executions done at discovery time
executions: u64,
/// Parent [`CorpusId`], if known /// Parent [`CorpusId`], if known
parent_id: Option<CorpusId>, parent_id: Option<CorpusId>,
/// If the testcase is "disabled" /// If the testcase is "disabled"
@ -145,6 +147,24 @@ impl<I> Testcase<I> {
&mut self.metadata_path &mut self.metadata_path
} }
/// Get the executions
#[inline]
pub fn executions(&self) -> &u64 {
&self.executions
}
/// Get the executions (mutable)
#[inline]
pub fn executions_mut(&mut self) -> &mut u64 {
&mut self.executions
}
/// Set the executions
#[inline]
pub fn set_executions(&mut self, executions: u64) {
self.executions = executions;
}
/// Get the execution time of the testcase /// Get the execution time of the testcase
#[inline] #[inline]
pub fn exec_time(&self) -> &Option<Duration> { pub fn exec_time(&self) -> &Option<Duration> {
@ -228,6 +248,7 @@ impl<I> Testcase<I> {
metadata_path: None, metadata_path: None,
exec_time: None, exec_time: None,
cached_len: None, cached_len: None,
executions: 0,
scheduled_count: 0, scheduled_count: 0,
parent_id: None, parent_id: None,
disabled: false, disabled: false,
@ -252,6 +273,7 @@ impl<I> Testcase<I> {
metadata_path: None, metadata_path: None,
exec_time: None, exec_time: None,
cached_len: None, cached_len: None,
executions: 0,
scheduled_count: 0, scheduled_count: 0,
parent_id: Some(parent_id), parent_id: Some(parent_id),
disabled: false, disabled: false,
@ -278,6 +300,7 @@ impl<I> Testcase<I> {
metadata_path: None, metadata_path: None,
exec_time: None, exec_time: None,
cached_len: None, cached_len: None,
executions: 0,
scheduled_count: 0, scheduled_count: 0,
parent_id: None, parent_id: None,
disabled: false, disabled: false,
@ -333,6 +356,7 @@ impl<I> Default for Testcase<I> {
#[cfg(feature = "std")] #[cfg(feature = "std")]
metadata_path: None, metadata_path: None,
disabled: false, disabled: false,
executions: 0,
objectives_found: 0, objectives_found: 0,
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
hit_feedbacks: Vec::new(), hit_feedbacks: Vec::new(),

View File

@ -345,6 +345,7 @@ pub fn run_observers_and_save_state<E, EM, I, OF, S, Z>(
if is_solution { if is_solution {
let mut new_testcase = Testcase::from(input.clone()); let mut new_testcase = Testcase::from(input.clone());
new_testcase.set_executions(*state.executions());
new_testcase.add_metadata(exitkind); new_testcase.add_metadata(exitkind);
new_testcase.set_parent_id_optional(*state.corpus().current()); new_testcase.set_parent_id_optional(*state.corpus().current());

View File

@ -360,6 +360,7 @@ where
OT: ObserversTuple<I, S> + Serialize, OT: ObserversTuple<I, S> + Serialize,
S: HasCorpus<I> S: HasCorpus<I>
+ MaybeHasClientPerfMonitor + MaybeHasClientPerfMonitor
+ HasExecutions
+ HasCurrentTestcase<I> + HasCurrentTestcase<I>
+ HasSolutions<I> + HasSolutions<I>
+ HasLastFoundTime + HasLastFoundTime
@ -420,6 +421,7 @@ where
let corpus = if exec_res.is_corpus() { let corpus = if exec_res.is_corpus() {
// Add the input to the main corpus // Add the input to the main corpus
let mut testcase = Testcase::from(input.clone()); let mut testcase = Testcase::from(input.clone());
testcase.set_executions(*state.executions());
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
self.feedback_mut() self.feedback_mut()
.append_hit_feedbacks(testcase.hit_feedbacks_mut())?; .append_hit_feedbacks(testcase.hit_feedbacks_mut())?;
@ -435,6 +437,7 @@ where
if exec_res.is_solution() { if exec_res.is_solution() {
// The input is a solution, add it to the respective corpus // The input is a solution, add it to the respective corpus
let mut testcase = Testcase::from(input.clone()); let mut testcase = Testcase::from(input.clone());
testcase.set_executions(*state.executions());
testcase.add_metadata(*exit_kind); testcase.add_metadata(*exit_kind);
testcase.set_parent_id_optional(*state.corpus().current()); testcase.set_parent_id_optional(*state.corpus().current());
if let Ok(mut tc) = state.current_testcase_mut() { if let Ok(mut tc) = state.current_testcase_mut() {
@ -675,6 +678,7 @@ where
let observers = executor.observers(); let observers = executor.observers();
// Always consider this to be "interesting" // Always consider this to be "interesting"
let mut testcase = Testcase::from(input.clone()); let mut testcase = Testcase::from(input.clone());
testcase.set_executions(*state.executions());
// Maybe a solution // Maybe a solution
#[cfg(not(feature = "introspection"))] #[cfg(not(feature = "introspection"))]
@ -763,6 +767,7 @@ where
fn add_disabled_input(&mut self, state: &mut S, input: I) -> Result<CorpusId, Error> { fn add_disabled_input(&mut self, state: &mut S, input: I) -> Result<CorpusId, Error> {
let mut testcase = Testcase::from(input.clone()); let mut testcase = Testcase::from(input.clone());
testcase.set_executions(*state.executions());
testcase.set_disabled(true); testcase.set_disabled(true);
// Add the disabled input to the main corpus // Add the disabled input to the main corpus
let id = state.corpus_mut().add_disabled(testcase)?; let id = state.corpus_mut().add_disabled(testcase)?;

View File

@ -284,6 +284,9 @@ where
.feedback_mut() .feedback_mut()
.is_interesting(state, manager, &base, &*observers, &exit_kind)?; .is_interesting(state, manager, &base, &*observers, &exit_kind)?;
let mut testcase = Testcase::from(base); let mut testcase = Testcase::from(base);
testcase.set_executions(*state.executions());
testcase.set_parent_id(base_corpus_id);
fuzzer fuzzer
.feedback_mut() .feedback_mut()
.append_metadata(state, manager, &*observers, &mut testcase)?; .append_metadata(state, manager, &*observers, &mut testcase)?;