More usable ListFeedback (#1959)
* real list feedback * add * fox * obs * fix * FMT * more * fmt * rev
This commit is contained in:
parent
7abc26ebc9
commit
15f4613894
@ -40,7 +40,7 @@ fn main() {
|
|||||||
// let args = vec!["test.exe".to_string(), "-f".to_string(), "@@".to_string()];
|
// let args = vec!["test.exe".to_string(), "-f".to_string(), "@@".to_string()];
|
||||||
|
|
||||||
let observer = unsafe { ListObserver::new("cov", &mut COVERAGE) };
|
let observer = unsafe { ListObserver::new("cov", &mut COVERAGE) };
|
||||||
let mut feedback = ListFeedback::with_observer(&observer);
|
let mut feedback = ListFeedback::new(&observer);
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let mut shmem_provider = Win32ShMemProvider::new().unwrap();
|
let mut shmem_provider = Win32ShMemProvider::new().unwrap();
|
||||||
|
|
||||||
|
172
libafl/src/feedbacks/list.rs
Normal file
172
libafl/src/feedbacks/list.rs
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
use alloc::string::{String, ToString};
|
||||||
|
use core::{fmt::Debug, hash::Hash, marker::PhantomData};
|
||||||
|
|
||||||
|
use hashbrown::HashSet;
|
||||||
|
use libafl_bolts::{Error, HasRefCnt, Named};
|
||||||
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
events::EventFirer,
|
||||||
|
executors::ExitKind,
|
||||||
|
feedbacks::Feedback,
|
||||||
|
observers::{ListObserver, ObserversTuple},
|
||||||
|
state::{HasNamedMetadata, State},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The metadata to remember past observed value
|
||||||
|
#[derive(Default, Serialize, Deserialize, Clone, Debug)]
|
||||||
|
#[serde(bound = "T: DeserializeOwned")]
|
||||||
|
#[cfg_attr(
|
||||||
|
any(not(feature = "serdeany_autoreg"), miri),
|
||||||
|
allow(clippy::unsafe_derive_deserialize)
|
||||||
|
)]
|
||||||
|
pub struct ListFeedbackMetadata<T>
|
||||||
|
where
|
||||||
|
T: Default + Copy + 'static + Serialize + Eq + Hash,
|
||||||
|
{
|
||||||
|
/// Contains the information of past observed set of values.
|
||||||
|
pub set: HashSet<T>,
|
||||||
|
/// A refcount used to know when we can remove this metadata
|
||||||
|
pub tcref: isize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ListFeedbackMetadata<T>
|
||||||
|
where
|
||||||
|
T: Default + Copy + 'static + Serialize + Eq + Hash,
|
||||||
|
{
|
||||||
|
/// The constructor
|
||||||
|
#[must_use]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
set: HashSet::<T>::new(),
|
||||||
|
tcref: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reset the inner hashset
|
||||||
|
pub fn reset(&mut self) -> Result<(), Error> {
|
||||||
|
self.set.clear();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> HasRefCnt for ListFeedbackMetadata<T>
|
||||||
|
where
|
||||||
|
T: Default + Copy + 'static + Serialize + Eq + Hash,
|
||||||
|
{
|
||||||
|
fn refcnt(&self) -> isize {
|
||||||
|
self.tcref
|
||||||
|
}
|
||||||
|
|
||||||
|
fn refcnt_mut(&mut self) -> &mut isize {
|
||||||
|
&mut self.tcref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consider interesting a testcase if the list in `ListObserver` is not empty.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct ListFeedback<T>
|
||||||
|
where
|
||||||
|
T: Hash + Eq,
|
||||||
|
{
|
||||||
|
name: String,
|
||||||
|
observer_name: String,
|
||||||
|
novelty: HashSet<T>,
|
||||||
|
phantom: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
libafl_bolts::impl_serdeany!(
|
||||||
|
ListFeedbackMetadata<T: Debug + Default + Copy + 'static + Serialize + DeserializeOwned + Eq + Hash>,
|
||||||
|
<u8>,<u16>,<u32>,<u64>,<i8>,<i16>,<i32>,<i64>,<bool>,<char>,<usize>
|
||||||
|
);
|
||||||
|
|
||||||
|
impl<S, T> Feedback<S> for ListFeedback<T>
|
||||||
|
where
|
||||||
|
S: State + HasNamedMetadata,
|
||||||
|
T: Debug + Serialize + Hash + Eq + DeserializeOwned + Default + Copy + 'static,
|
||||||
|
{
|
||||||
|
fn init_state(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
|
// eprintln!("self.name {:#?}", &self.name);
|
||||||
|
state.add_named_metadata(&self.name, ListFeedbackMetadata::<T>::default());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
#[allow(clippy::wrong_self_convention)]
|
||||||
|
fn is_interesting<EM, OT>(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
_manager: &mut EM,
|
||||||
|
_input: &S::Input,
|
||||||
|
observers: &OT,
|
||||||
|
_exit_kind: &ExitKind,
|
||||||
|
) -> Result<bool, Error>
|
||||||
|
where
|
||||||
|
EM: EventFirer<State = S>,
|
||||||
|
OT: ObserversTuple<S>,
|
||||||
|
{
|
||||||
|
// TODO Replace with match_name_type when stable
|
||||||
|
let observer = observers
|
||||||
|
.match_name::<ListObserver<T>>(&self.observer_name)
|
||||||
|
.unwrap();
|
||||||
|
// TODO register the list content in a testcase metadata
|
||||||
|
self.novelty.clear();
|
||||||
|
// can't fail
|
||||||
|
let history_set = state
|
||||||
|
.named_metadata_map_mut()
|
||||||
|
.get_mut::<ListFeedbackMetadata<T>>(&self.name)
|
||||||
|
.unwrap();
|
||||||
|
for v in observer.list() {
|
||||||
|
if !history_set.set.contains(v) {
|
||||||
|
self.novelty.insert(*v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(!self.novelty.is_empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn append_metadata<EM, OT>(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
_manager: &mut EM,
|
||||||
|
_observers: &OT,
|
||||||
|
_testcase: &mut crate::corpus::Testcase<<S>::Input>,
|
||||||
|
) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
OT: ObserversTuple<S>,
|
||||||
|
EM: EventFirer<State = S>,
|
||||||
|
{
|
||||||
|
let history_set = state
|
||||||
|
.named_metadata_map_mut()
|
||||||
|
.get_mut::<ListFeedbackMetadata<T>>(&self.name)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
for v in &self.novelty {
|
||||||
|
history_set.set.insert(*v);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Named for ListFeedback<T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + Hash + Eq + DeserializeOwned,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
self.name.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ListFeedback<T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + Hash + Eq + DeserializeOwned,
|
||||||
|
{
|
||||||
|
/// Creates a new [`ListFeedback`], deciding if the given [`ListObserver`] value of a run is interesting.
|
||||||
|
#[must_use]
|
||||||
|
pub fn new(observer: &ListObserver<T>) -> Self {
|
||||||
|
Self {
|
||||||
|
name: observer.name().to_string(),
|
||||||
|
observer_name: observer.name().to_string(),
|
||||||
|
novelty: HashSet::<T>::new(),
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -28,9 +28,6 @@ use crate::{
|
|||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The prefix of the metadata names
|
|
||||||
pub const MAPFEEDBACK_PREFIX: &str = "mapfeedback_metadata_";
|
|
||||||
|
|
||||||
/// A [`MapFeedback`] that implements the AFL algorithm using an [`OrReducer`] combining the bits for the history map and the bit from ``HitcountsMapObserver``.
|
/// A [`MapFeedback`] that implements the AFL algorithm using an [`OrReducer`] combining the bits for the history map and the bit from ``HitcountsMapObserver``.
|
||||||
pub type AflMapFeedback<O, S, T> = MapFeedback<DifferentIsNovel, O, OrReducer, S, T>;
|
pub type AflMapFeedback<O, S, T> = MapFeedback<DifferentIsNovel, O, OrReducer, S, T>;
|
||||||
|
|
||||||
@ -700,7 +697,7 @@ where
|
|||||||
Self {
|
Self {
|
||||||
indexes: false,
|
indexes: false,
|
||||||
novelties: None,
|
novelties: None,
|
||||||
name: MAPFEEDBACK_PREFIX.to_string() + map_observer.name(),
|
name: map_observer.name().to_string(),
|
||||||
observer_name: map_observer.name().to_string(),
|
observer_name: map_observer.name().to_string(),
|
||||||
stats_name: create_stats_name(map_observer.name()),
|
stats_name: create_stats_name(map_observer.name()),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
@ -713,7 +710,7 @@ where
|
|||||||
Self {
|
Self {
|
||||||
indexes: track_indexes,
|
indexes: track_indexes,
|
||||||
novelties: if track_novelties { Some(vec![]) } else { None },
|
novelties: if track_novelties { Some(vec![]) } else { None },
|
||||||
name: MAPFEEDBACK_PREFIX.to_string() + map_observer.name(),
|
name: map_observer.name().to_string(),
|
||||||
observer_name: map_observer.name().to_string(),
|
observer_name: map_observer.name().to_string(),
|
||||||
stats_name: create_stats_name(map_observer.name()),
|
stats_name: create_stats_name(map_observer.name()),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
@ -25,6 +25,8 @@ pub use new_hash_feedback::NewHashFeedbackMetadata;
|
|||||||
pub mod nautilus;
|
pub mod nautilus;
|
||||||
pub mod transferred;
|
pub mod transferred;
|
||||||
|
|
||||||
|
/// The module for list feedback
|
||||||
|
pub mod list;
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::{String, ToString};
|
||||||
use core::{
|
use core::{
|
||||||
fmt::{self, Debug, Formatter},
|
fmt::{self, Debug, Formatter},
|
||||||
@ -32,6 +34,7 @@ use core::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use libafl_bolts::Named;
|
use libafl_bolts::Named;
|
||||||
|
pub use list::*;
|
||||||
#[cfg(feature = "nautilus")]
|
#[cfg(feature = "nautilus")]
|
||||||
pub use nautilus::*;
|
pub use nautilus::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -40,7 +43,7 @@ use crate::{
|
|||||||
corpus::Testcase,
|
corpus::Testcase,
|
||||||
events::EventFirer,
|
events::EventFirer,
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
observers::{ListObserver, ObserversTuple, TimeObserver},
|
observers::{ObserversTuple, TimeObserver},
|
||||||
state::State,
|
state::State,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -972,79 +975,6 @@ impl TimeFeedback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consider interesting a testcase if the list in `ListObserver` is not empty.
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
|
||||||
pub struct ListFeedback<T>
|
|
||||||
where
|
|
||||||
T: Debug + Serialize + serde::de::DeserializeOwned,
|
|
||||||
{
|
|
||||||
name: String,
|
|
||||||
last_addr: usize,
|
|
||||||
phantom: PhantomData<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, T> Feedback<S> for ListFeedback<T>
|
|
||||||
where
|
|
||||||
S: State,
|
|
||||||
T: Debug + Serialize + serde::de::DeserializeOwned,
|
|
||||||
{
|
|
||||||
#[allow(clippy::wrong_self_convention)]
|
|
||||||
fn is_interesting<EM, OT>(
|
|
||||||
&mut self,
|
|
||||||
_state: &mut S,
|
|
||||||
_manager: &mut EM,
|
|
||||||
_input: &S::Input,
|
|
||||||
observers: &OT,
|
|
||||||
_exit_kind: &ExitKind,
|
|
||||||
) -> Result<bool, Error>
|
|
||||||
where
|
|
||||||
EM: EventFirer<State = S>,
|
|
||||||
OT: ObserversTuple<S>,
|
|
||||||
{
|
|
||||||
// TODO Replace with match_name_type when stable
|
|
||||||
let observer = observers
|
|
||||||
.match_name::<ListObserver<T>>(self.name())
|
|
||||||
.unwrap();
|
|
||||||
// TODO register the list content in a testcase metadata
|
|
||||||
Ok(!observer.list().is_empty())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Named for ListFeedback<T>
|
|
||||||
where
|
|
||||||
T: Debug + Serialize + serde::de::DeserializeOwned,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn name(&self) -> &str {
|
|
||||||
self.name.as_str()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ListFeedback<T>
|
|
||||||
where
|
|
||||||
T: Debug + Serialize + serde::de::DeserializeOwned,
|
|
||||||
{
|
|
||||||
/// Creates a new [`ListFeedback`], deciding if the value of a [`ListObserver`] with the given `name` of a run is interesting.
|
|
||||||
#[must_use]
|
|
||||||
pub fn new(name: &'static str) -> Self {
|
|
||||||
Self {
|
|
||||||
name: name.to_string(),
|
|
||||||
last_addr: 0,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new [`TimeFeedback`], deciding if the given [`ListObserver`] value of a run is interesting.
|
|
||||||
#[must_use]
|
|
||||||
pub fn with_observer(observer: &ListObserver<T>) -> Self {
|
|
||||||
Self {
|
|
||||||
name: observer.name().to_string(),
|
|
||||||
last_addr: 0,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The [`ConstFeedback`] reports the same value, always.
|
/// The [`ConstFeedback`] reports the same value, always.
|
||||||
/// It can be used to enable or disable feedback results through composition.
|
/// It can be used to enable or disable feedback results through composition.
|
||||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
73
libafl/src/observers/list.rs
Normal file
73
libafl/src/observers/list.rs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
use alloc::{
|
||||||
|
string::{String, ToString},
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
|
use core::fmt::Debug;
|
||||||
|
|
||||||
|
use libafl_bolts::{ownedref::OwnedMutPtr, Error, Named};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{inputs::UsesInput, observers::Observer};
|
||||||
|
|
||||||
|
/// A simple observer with a list of things.
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
#[serde(bound = "T: serde::de::DeserializeOwned")]
|
||||||
|
#[allow(clippy::unsafe_derive_deserialize)]
|
||||||
|
pub struct ListObserver<T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize,
|
||||||
|
{
|
||||||
|
name: String,
|
||||||
|
/// The list
|
||||||
|
list: OwnedMutPtr<Vec<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ListObserver<T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
/// Creates a new [`ListObserver`] with the given name.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// Will dereference the list.
|
||||||
|
/// The list may not move in memory.
|
||||||
|
#[must_use]
|
||||||
|
pub unsafe fn new(name: &'static str, list: *mut Vec<T>) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.to_string(),
|
||||||
|
list: OwnedMutPtr::Ptr(list),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a list ref
|
||||||
|
#[must_use]
|
||||||
|
pub fn list(&self) -> &Vec<T> {
|
||||||
|
self.list.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a list mut
|
||||||
|
#[must_use]
|
||||||
|
pub fn list_mut(&mut self) -> &mut Vec<T> {
|
||||||
|
self.list.as_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, T> Observer<S> for ListObserver<T>
|
||||||
|
where
|
||||||
|
S: UsesInput,
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
|
||||||
|
self.list.as_mut().clear();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Named for ListObserver<T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
}
|
@ -20,17 +20,17 @@ pub mod concolic;
|
|||||||
|
|
||||||
pub mod value;
|
pub mod value;
|
||||||
|
|
||||||
use alloc::{
|
/// List observer
|
||||||
string::{String, ToString},
|
pub mod list;
|
||||||
vec::Vec,
|
use alloc::string::{String, ToString};
|
||||||
};
|
|
||||||
use core::{fmt::Debug, time::Duration};
|
use core::{fmt::Debug, time::Duration};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use libafl_bolts::current_time;
|
use libafl_bolts::current_time;
|
||||||
use libafl_bolts::{ownedref::OwnedMutPtr, tuples::MatchName, Named};
|
use libafl_bolts::{tuples::MatchName, Named};
|
||||||
|
pub use list::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
pub use value::*;
|
pub use value::*;
|
||||||
|
|
||||||
@ -526,73 +526,11 @@ where
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A simple observer with a list of things.
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
|
||||||
#[serde(bound = "T: serde::de::DeserializeOwned")]
|
|
||||||
#[allow(clippy::unsafe_derive_deserialize)]
|
|
||||||
pub struct ListObserver<T>
|
|
||||||
where
|
|
||||||
T: Debug + Serialize,
|
|
||||||
{
|
|
||||||
name: String,
|
|
||||||
/// The list
|
|
||||||
list: OwnedMutPtr<Vec<T>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ListObserver<T>
|
|
||||||
where
|
|
||||||
T: Debug + Serialize + serde::de::DeserializeOwned,
|
|
||||||
{
|
|
||||||
/// Creates a new [`ListObserver`] with the given name.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
/// Will dereference the list.
|
|
||||||
/// The list may not move in memory.
|
|
||||||
#[must_use]
|
|
||||||
pub unsafe fn new(name: &'static str, list: *mut Vec<T>) -> Self {
|
|
||||||
Self {
|
|
||||||
name: name.to_string(),
|
|
||||||
list: OwnedMutPtr::Ptr(list),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a list ref
|
|
||||||
#[must_use]
|
|
||||||
pub fn list(&self) -> &Vec<T> {
|
|
||||||
self.list.as_ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a list mut
|
|
||||||
#[must_use]
|
|
||||||
pub fn list_mut(&mut self) -> &mut Vec<T> {
|
|
||||||
self.list.as_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, T> Observer<S> for ListObserver<T>
|
|
||||||
where
|
|
||||||
S: UsesInput,
|
|
||||||
T: Debug + Serialize + serde::de::DeserializeOwned,
|
|
||||||
{
|
|
||||||
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
|
|
||||||
self.list.as_mut().clear();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Named for ListObserver<T>
|
|
||||||
where
|
|
||||||
T: Debug + Serialize + serde::de::DeserializeOwned,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
|
||||||
&self.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// `Observer` Python bindings
|
/// `Observer` Python bindings
|
||||||
#[cfg(feature = "python")]
|
#[cfg(feature = "python")]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
|
use alloc::vec::Vec;
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
|
|
||||||
@ -603,7 +541,7 @@ pub mod pybind {
|
|||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{Debug, Observer, ObserversTuple, String, Vec};
|
use super::{Debug, Observer, ObserversTuple, String};
|
||||||
use crate::{
|
use crate::{
|
||||||
executors::{pybind::PythonExitKind, ExitKind},
|
executors::{pybind::PythonExitKind, ExitKind},
|
||||||
inputs::{BytesInput, HasBytesVec},
|
inputs::{BytesInput, HasBytesVec},
|
||||||
|
@ -3,7 +3,7 @@ use std::ffi::c_int;
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
events::{ProgressReporter, SimpleEventManager},
|
events::{ProgressReporter, SimpleEventManager},
|
||||||
executors::HasObservers,
|
executors::HasObservers,
|
||||||
feedbacks::{MapFeedbackMetadata, MAPFEEDBACK_PREFIX},
|
feedbacks::MapFeedbackMetadata,
|
||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
monitors::SimpleMonitor,
|
monitors::SimpleMonitor,
|
||||||
stages::{HasCurrentStage, StagesTuple},
|
stages::{HasCurrentStage, StagesTuple},
|
||||||
@ -35,7 +35,7 @@ where
|
|||||||
ST: StagesTuple<E, EM, S, F>,
|
ST: StagesTuple<E, EM, S, F>,
|
||||||
{
|
{
|
||||||
let meta = state
|
let meta = state
|
||||||
.named_metadata::<MapFeedbackMetadata<u8>>(&(MAPFEEDBACK_PREFIX.to_string() + "edges"))
|
.named_metadata::<MapFeedbackMetadata<u8>>("edges")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let observed = meta.history_map.iter().filter(|&&e| e != 0).count();
|
let observed = meta.history_map.iter().filter(|&&e| e != 0).count();
|
||||||
let total = meta.history_map.len();
|
let total = meta.history_map.len();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user