diff --git a/libafl/src/stages/calibrate.rs b/libafl/src/stages/calibrate.rs index 8498e044f3..14e5ed043c 100644 --- a/libafl/src/stages/calibrate.rs +++ b/libafl/src/stages/calibrate.rs @@ -40,10 +40,10 @@ impl_serdeany!(UnstableEntriesMetadata); impl UnstableEntriesMetadata { #[must_use] /// Create a new [`struct@UnstableEntriesMetadata`] - pub fn new(entries: HashSet, map_len: usize) -> Self { + pub fn new() -> Self { Self { - unstable_entries: entries, - map_len, + unstable_entries: HashSet::new(), + map_len: 0, } } @@ -60,6 +60,12 @@ impl UnstableEntriesMetadata { } } +impl Default for UnstableEntriesMetadata { + fn default() -> Self { + Self::new() + } +} + /// Default name for `CalibrationStage`; derived from AFL++ pub const CALIBRATION_STAGE_NAME: &str = "calibration"; /// The calibration stage will measure the average exec time and the target's stability for this input. @@ -220,25 +226,20 @@ where i += 1; } + let mut send_default_stability = false; let unstable_found = !unstable_entries.is_empty(); if unstable_found { + let metadata = state.metadata_or_insert_with(UnstableEntriesMetadata::new); + // If we see new stable entries executing this new corpus entries, then merge with the existing one - if state.has_metadata::() { - let existing = state - .metadata_map_mut() - .get_mut::() - .unwrap(); - for item in unstable_entries { - existing.unstable_entries.insert(item); // Insert newly found items - } - existing.map_len = map_len; - } else { - state.add_metadata::(UnstableEntriesMetadata::new( - HashSet::from_iter(unstable_entries), - map_len, - )); + for item in unstable_entries { + metadata.unstable_entries.insert(item); // Insert newly found items } - }; + metadata.map_len = map_len; + } else if !state.has_metadata::() { + send_default_stability = true; + state.add_metadata(UnstableEntriesMetadata::new()); + } // If weighted scheduler or powerscheduler is used, update it if state.has_metadata::() { @@ -300,6 +301,7 @@ where if let Some(meta) = state.metadata_map().get::() { let unstable_entries = meta.unstable_entries().len(); let map_len = meta.map_len(); + debug_assert_ne!(map_len, 0, "The map_len must never be 0"); mgr.fire( state, Event::UpdateUserStats { @@ -315,6 +317,18 @@ where }, )?; } + } else if send_default_stability { + mgr.fire( + state, + Event::UpdateUserStats { + name: Cow::from("stability"), + value: UserStats::new( + UserStatsValue::Ratio(map_len as u64, map_len as u64), + AggregatorOps::Avg, + ), + phantom: PhantomData, + }, + )?; } Ok(())