* fix * lol * lol * clp fixer * clp fixer * revert cargo.toml
This commit is contained in:
parent
fa8a576ef0
commit
373fe03633
@ -39,7 +39,6 @@ default = [
|
|||||||
"regex",
|
"regex",
|
||||||
"serdeany_autoreg",
|
"serdeany_autoreg",
|
||||||
"libafl_bolts/xxh3",
|
"libafl_bolts/xxh3",
|
||||||
"tui_monitor",
|
|
||||||
]
|
]
|
||||||
document-features = ["dep:document-features"]
|
document-features = ["dep:document-features"]
|
||||||
|
|
||||||
|
@ -17,6 +17,6 @@ pub fn main() {
|
|||||||
let _client_stats = ClientStats::default();
|
let _client_stats = ClientStats::default();
|
||||||
let mut client_stats_manager = ClientStatsManager::default();
|
let mut client_stats_manager = ClientStatsManager::default();
|
||||||
|
|
||||||
monitor.display(&mut client_stats_manager, "Test", ClientId(0));
|
let _ = monitor.display(&mut client_stats_manager, "Test", ClientId(0));
|
||||||
sleep(Duration::from_secs(10));
|
sleep(Duration::from_secs(10));
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ where
|
|||||||
// Perform the optimization!
|
// Perform the optimization!
|
||||||
opt.check(&[]);
|
opt.check(&[]);
|
||||||
|
|
||||||
let res = if let Some(model) = opt.get_model() {
|
if let Some(model) = opt.get_model() {
|
||||||
let mut removed = Vec::with_capacity(state.corpus().count());
|
let mut removed = Vec::with_capacity(state.corpus().count());
|
||||||
for (seed, (id, _)) in seed_exprs {
|
for (seed, (id, _)) in seed_exprs {
|
||||||
// if the model says the seed isn't there, mark it for deletion
|
// if the model says the seed isn't there, mark it for deletion
|
||||||
@ -214,11 +214,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
*state.corpus_mut().current_mut() = None; //we may have removed the current ID from the corpus
|
*state.corpus_mut().current_mut() = None; //we may have removed the current ID from the corpus
|
||||||
Ok(())
|
return Ok(());
|
||||||
} else {
|
}
|
||||||
Err(Error::unknown("Corpus minimization failed; unsat."))
|
Err(Error::unknown("Corpus minimization failed; unsat."))
|
||||||
};
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ where
|
|||||||
&mut self.client_stats_manager,
|
&mut self.client_stats_manager,
|
||||||
"Broker Heartbeat",
|
"Broker Heartbeat",
|
||||||
ClientId(0),
|
ClientId(0),
|
||||||
);
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,7 +114,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Handle arriving events in the broker
|
/// Handle arriving events in the broker
|
||||||
#[expect(clippy::unnecessary_wraps)]
|
|
||||||
fn handle_in_broker(
|
fn handle_in_broker(
|
||||||
monitor: &mut MT,
|
monitor: &mut MT,
|
||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
@ -123,10 +122,10 @@ where
|
|||||||
) -> Result<BrokerEventResult, Error> {
|
) -> Result<BrokerEventResult, Error> {
|
||||||
let stats = event.stats();
|
let stats = event.stats();
|
||||||
|
|
||||||
client_stats_manager.client_stats_insert(ClientId(0));
|
client_stats_manager.client_stats_insert(client_id)?;
|
||||||
client_stats_manager.update_client_stats_for(ClientId(0), |client_stat| {
|
client_stats_manager.update_client_stats_for(client_id, |client_stat| {
|
||||||
client_stat.update_executions(stats.executions, stats.time);
|
client_stat.update_executions(stats.executions, stats.time);
|
||||||
});
|
})?;
|
||||||
|
|
||||||
let event = event.event();
|
let event = event.event();
|
||||||
match &event {
|
match &event {
|
||||||
@ -141,21 +140,21 @@ where
|
|||||||
client_id
|
client_id
|
||||||
};
|
};
|
||||||
|
|
||||||
client_stats_manager.client_stats_insert(id);
|
client_stats_manager.client_stats_insert(id)?;
|
||||||
client_stats_manager.update_client_stats_for(id, |client_stat| {
|
client_stats_manager.update_client_stats_for(id, |client_stat| {
|
||||||
client_stat.update_corpus_size(*corpus_size as u64);
|
client_stat.update_corpus_size(*corpus_size as u64);
|
||||||
});
|
})?;
|
||||||
monitor.display(client_stats_manager, event.name(), id);
|
monitor.display(client_stats_manager, event.name(), id)?;
|
||||||
Ok(BrokerEventResult::Forward)
|
Ok(BrokerEventResult::Forward)
|
||||||
}
|
}
|
||||||
Event::Heartbeat => Ok(BrokerEventResult::Handled),
|
Event::Heartbeat => Ok(BrokerEventResult::Handled),
|
||||||
Event::UpdateUserStats { name, value, .. } => {
|
Event::UpdateUserStats { name, value, .. } => {
|
||||||
client_stats_manager.client_stats_insert(client_id);
|
client_stats_manager.client_stats_insert(client_id)?;
|
||||||
client_stats_manager.update_client_stats_for(client_id, |client_stat| {
|
client_stats_manager.update_client_stats_for(client_id, |client_stat| {
|
||||||
client_stat.update_user_stats(name.clone(), value.clone());
|
client_stat.update_user_stats(name.clone(), value.clone());
|
||||||
});
|
})?;
|
||||||
client_stats_manager.aggregate(name);
|
client_stats_manager.aggregate(name);
|
||||||
monitor.display(client_stats_manager, event.name(), client_id);
|
monitor.display(client_stats_manager, event.name(), client_id)?;
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
}
|
}
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
@ -166,24 +165,24 @@ where
|
|||||||
// TODO: The monitor buffer should be added on client add.
|
// TODO: The monitor buffer should be added on client add.
|
||||||
|
|
||||||
// Get the client for the staterestorer ID
|
// Get the client for the staterestorer ID
|
||||||
client_stats_manager.client_stats_insert(client_id);
|
client_stats_manager.client_stats_insert(client_id)?;
|
||||||
client_stats_manager.update_client_stats_for(client_id, |client_stat| {
|
client_stats_manager.update_client_stats_for(client_id, |client_stat| {
|
||||||
// Update the performance monitor for this client
|
// Update the performance monitor for this client
|
||||||
client_stat.update_introspection_stats((**introspection_stats).clone());
|
client_stat.update_introspection_stats((**introspection_stats).clone());
|
||||||
});
|
})?;
|
||||||
|
|
||||||
// Display the monitor via `.display` only on core #1
|
// Display the monitor via `.display` only on core #1
|
||||||
monitor.display(client_stats_manager, event.name(), client_id);
|
monitor.display(client_stats_manager, event.name(), client_id)?;
|
||||||
|
|
||||||
// Correctly handled the event
|
// Correctly handled the event
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
}
|
}
|
||||||
Event::Objective { objective_size, .. } => {
|
Event::Objective { objective_size, .. } => {
|
||||||
client_stats_manager.client_stats_insert(client_id);
|
client_stats_manager.client_stats_insert(client_id)?;
|
||||||
client_stats_manager.update_client_stats_for(client_id, |client_stat| {
|
client_stats_manager.update_client_stats_for(client_id, |client_stat| {
|
||||||
client_stat.update_objective_size(*objective_size as u64);
|
client_stat.update_objective_size(*objective_size as u64);
|
||||||
});
|
})?;
|
||||||
monitor.display(client_stats_manager, event.name(), client_id);
|
monitor.display(client_stats_manager, event.name(), client_id)?;
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
}
|
}
|
||||||
Event::Log {
|
Event::Log {
|
||||||
|
@ -268,10 +268,10 @@ where
|
|||||||
let timeout = current_time() + parent_lock.node_descriptor.timeout;
|
let timeout = current_time() + parent_lock.node_descriptor.timeout;
|
||||||
|
|
||||||
parent_lock.parent = loop {
|
parent_lock.parent = loop {
|
||||||
log::debug!("Trying to connect to parent @ {}..", parent_addr);
|
log::debug!("Trying to connect to parent @ {parent_addr}..");
|
||||||
match TcpStream::connect(parent_addr).await {
|
match TcpStream::connect(parent_addr).await {
|
||||||
Ok(stream) => {
|
Ok(stream) => {
|
||||||
log::debug!("Connected to parent @ {}", parent_addr);
|
log::debug!("Connected to parent @ {parent_addr}");
|
||||||
|
|
||||||
break Some(stream);
|
break Some(stream);
|
||||||
}
|
}
|
||||||
@ -302,10 +302,10 @@ where
|
|||||||
|
|
||||||
// The main listening loop. Should never fail.
|
// The main listening loop. Should never fail.
|
||||||
'listening: loop {
|
'listening: loop {
|
||||||
log::debug!("listening for children on {:?}...", listener);
|
log::debug!("listening for children on {listener:?}...");
|
||||||
match listener.accept().await {
|
match listener.accept().await {
|
||||||
Ok((mut stream, addr)) => {
|
Ok((mut stream, addr)) => {
|
||||||
log::debug!("{} joined the children.", addr);
|
log::debug!("{addr} joined the children.");
|
||||||
let mut state_guard = state.write().await;
|
let mut state_guard = state.write().await;
|
||||||
|
|
||||||
if let Err(e) = state_guard
|
if let Err(e) = state_guard
|
||||||
@ -487,7 +487,7 @@ where
|
|||||||
|
|
||||||
// Garbage collect disconnected children
|
// Garbage collect disconnected children
|
||||||
for id_to_remove in &ids_to_remove {
|
for id_to_remove in &ids_to_remove {
|
||||||
log::debug!("Child {:?} has been garbage collected.", id_to_remove);
|
log::debug!("Child {id_to_remove:?} has been garbage collected.");
|
||||||
self.children.remove(id_to_remove);
|
self.children.remove(id_to_remove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -596,7 +596,7 @@ where
|
|||||||
|
|
||||||
// Garbage collect disconnected children
|
// Garbage collect disconnected children
|
||||||
for id_to_remove in &ids_to_remove {
|
for id_to_remove in &ids_to_remove {
|
||||||
log::debug!("Child {:?} has been garbage collected.", id_to_remove);
|
log::debug!("Child {id_to_remove:?} has been garbage collected.");
|
||||||
self.children.remove(id_to_remove);
|
self.children.remove(id_to_remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ use alloc::vec::Vec;
|
|||||||
use core::sync::atomic::{Ordering, compiler_fence};
|
use core::sync::atomic::{Ordering, compiler_fence};
|
||||||
use core::{fmt::Debug, marker::PhantomData, time::Duration};
|
use core::{fmt::Debug, marker::PhantomData, time::Duration};
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use hashbrown::HashMap;
|
||||||
use libafl_bolts::ClientId;
|
use libafl_bolts::ClientId;
|
||||||
#[cfg(all(feature = "std", any(windows, not(feature = "fork"))))]
|
#[cfg(all(feature = "std", any(windows, not(feature = "fork"))))]
|
||||||
use libafl_bolts::os::startable_self;
|
use libafl_bolts::os::startable_self;
|
||||||
@ -200,7 +202,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Handle arriving events in the broker
|
/// Handle arriving events in the broker
|
||||||
#[expect(clippy::unnecessary_wraps)]
|
|
||||||
fn handle_in_broker(
|
fn handle_in_broker(
|
||||||
monitor: &mut MT,
|
monitor: &mut MT,
|
||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
@ -208,32 +209,32 @@ where
|
|||||||
) -> Result<BrokerEventResult, Error> {
|
) -> Result<BrokerEventResult, Error> {
|
||||||
let stats = event.stats();
|
let stats = event.stats();
|
||||||
|
|
||||||
client_stats_manager.client_stats_insert(ClientId(0));
|
client_stats_manager.client_stats_insert(ClientId(0))?;
|
||||||
client_stats_manager.update_client_stats_for(ClientId(0), |client_stat| {
|
client_stats_manager.update_client_stats_for(ClientId(0), |client_stat| {
|
||||||
client_stat.update_executions(stats.executions, stats.time);
|
client_stat.update_executions(stats.executions, stats.time);
|
||||||
});
|
})?;
|
||||||
|
|
||||||
let event = event.event();
|
let event = event.event();
|
||||||
match event {
|
match event {
|
||||||
Event::NewTestcase { corpus_size, .. } => {
|
Event::NewTestcase { corpus_size, .. } => {
|
||||||
client_stats_manager.client_stats_insert(ClientId(0));
|
client_stats_manager.client_stats_insert(ClientId(0))?;
|
||||||
client_stats_manager.update_client_stats_for(ClientId(0), |client_stat| {
|
client_stats_manager.update_client_stats_for(ClientId(0), |client_stat| {
|
||||||
client_stat.update_corpus_size(*corpus_size as u64);
|
client_stat.update_corpus_size(*corpus_size as u64);
|
||||||
});
|
})?;
|
||||||
monitor.display(client_stats_manager, event.name(), ClientId(0));
|
monitor.display(client_stats_manager, event.name(), ClientId(0))?;
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
}
|
}
|
||||||
Event::Heartbeat => {
|
Event::Heartbeat => {
|
||||||
monitor.display(client_stats_manager, event.name(), ClientId(0));
|
monitor.display(client_stats_manager, event.name(), ClientId(0))?;
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
}
|
}
|
||||||
Event::UpdateUserStats { name, value, .. } => {
|
Event::UpdateUserStats { name, value, .. } => {
|
||||||
client_stats_manager.client_stats_insert(ClientId(0));
|
client_stats_manager.client_stats_insert(ClientId(0))?;
|
||||||
client_stats_manager.update_client_stats_for(ClientId(0), |client_stat| {
|
client_stats_manager.update_client_stats_for(ClientId(0), |client_stat| {
|
||||||
client_stat.update_user_stats(name.clone(), value.clone());
|
client_stat.update_user_stats(name.clone(), value.clone());
|
||||||
});
|
})?;
|
||||||
client_stats_manager.aggregate(name);
|
client_stats_manager.aggregate(name);
|
||||||
monitor.display(client_stats_manager, event.name(), ClientId(0));
|
monitor.display(client_stats_manager, event.name(), ClientId(0))?;
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
}
|
}
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
@ -244,16 +245,16 @@ where
|
|||||||
// TODO: The monitor buffer should be added on client add.
|
// TODO: The monitor buffer should be added on client add.
|
||||||
client_stats_manager.update_client_stats_for(ClientId(0), |client_stat| {
|
client_stats_manager.update_client_stats_for(ClientId(0), |client_stat| {
|
||||||
client_stat.update_introspection_stats((**introspection_stats).clone());
|
client_stat.update_introspection_stats((**introspection_stats).clone());
|
||||||
});
|
})?;
|
||||||
monitor.display(client_stats_manager, event.name(), ClientId(0));
|
monitor.display(client_stats_manager, event.name(), ClientId(0))?;
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
}
|
}
|
||||||
Event::Objective { objective_size, .. } => {
|
Event::Objective { objective_size, .. } => {
|
||||||
client_stats_manager.client_stats_insert(ClientId(0));
|
client_stats_manager.client_stats_insert(ClientId(0))?;
|
||||||
client_stats_manager.update_client_stats_for(ClientId(0), |client_stat| {
|
client_stats_manager.update_client_stats_for(ClientId(0), |client_stat| {
|
||||||
client_stat.update_objective_size(*objective_size as u64);
|
client_stat.update_objective_size(*objective_size as u64);
|
||||||
});
|
})?;
|
||||||
monitor.display(client_stats_manager, event.name(), ClientId(0));
|
monitor.display(client_stats_manager, event.name(), ClientId(0))?;
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
}
|
}
|
||||||
Event::Log {
|
Event::Log {
|
||||||
@ -525,7 +526,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we're restarting, deserialize the old state.
|
// If we're restarting, deserialize the old state.
|
||||||
let (state, mgr) = match staterestorer.restore::<(S, Duration, Vec<ClientStats>)>()? {
|
let (state, mgr) =
|
||||||
|
match staterestorer.restore::<(S, Duration, HashMap<ClientId, ClientStats>)>()? {
|
||||||
None => {
|
None => {
|
||||||
log::info!("First run. Let's set it all up");
|
log::info!("First run. Let's set it all up");
|
||||||
// Mgr to send and receive msgs from/to all other fuzzer instances
|
// Mgr to send and receive msgs from/to all other fuzzer instances
|
||||||
|
@ -317,7 +317,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Handle arriving events in the broker
|
/// Handle arriving events in the broker
|
||||||
#[expect(clippy::unnecessary_wraps)]
|
|
||||||
fn handle_in_broker(
|
fn handle_in_broker(
|
||||||
monitor: &mut MT,
|
monitor: &mut MT,
|
||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
@ -326,10 +325,10 @@ where
|
|||||||
) -> Result<BrokerEventResult, Error> {
|
) -> Result<BrokerEventResult, Error> {
|
||||||
let stats = event.stats();
|
let stats = event.stats();
|
||||||
|
|
||||||
client_stats_manager.client_stats_insert(ClientId(0));
|
client_stats_manager.client_stats_insert(client_id)?;
|
||||||
client_stats_manager.update_client_stats_for(ClientId(0), |client_stat| {
|
client_stats_manager.update_client_stats_for(client_id, |client_stat| {
|
||||||
client_stat.update_executions(stats.executions, stats.time);
|
client_stat.update_executions(stats.executions, stats.time);
|
||||||
});
|
})?;
|
||||||
|
|
||||||
let event = event.event();
|
let event = event.event();
|
||||||
match event {
|
match event {
|
||||||
@ -343,28 +342,25 @@ where
|
|||||||
} else {
|
} else {
|
||||||
client_id
|
client_id
|
||||||
};
|
};
|
||||||
client_stats_manager.client_stats_insert(id);
|
client_stats_manager.client_stats_insert(id)?;
|
||||||
client_stats_manager.update_client_stats_for(id, |client| {
|
client_stats_manager.update_client_stats_for(id, |client| {
|
||||||
client.update_corpus_size(*corpus_size as u64);
|
client.update_corpus_size(*corpus_size as u64);
|
||||||
});
|
})?;
|
||||||
monitor.display(client_stats_manager, event.name(), id);
|
monitor.display(client_stats_manager, event.name(), id)?;
|
||||||
Ok(BrokerEventResult::Forward)
|
Ok(BrokerEventResult::Forward)
|
||||||
}
|
}
|
||||||
Event::Heartbeat => {
|
Event::Heartbeat => Ok(BrokerEventResult::Handled),
|
||||||
monitor.display(client_stats_manager, event.name(), client_id);
|
|
||||||
Ok(BrokerEventResult::Handled)
|
|
||||||
}
|
|
||||||
Event::UpdateUserStats {
|
Event::UpdateUserStats {
|
||||||
name,
|
name,
|
||||||
value,
|
value,
|
||||||
phantom: _,
|
phantom: _,
|
||||||
} => {
|
} => {
|
||||||
client_stats_manager.client_stats_insert(client_id);
|
client_stats_manager.client_stats_insert(client_id)?;
|
||||||
client_stats_manager.update_client_stats_for(client_id, |client| {
|
client_stats_manager.update_client_stats_for(client_id, |client| {
|
||||||
client.update_user_stats(name.clone(), value.clone());
|
client.update_user_stats(name.clone(), value.clone());
|
||||||
});
|
})?;
|
||||||
client_stats_manager.aggregate(name);
|
client_stats_manager.aggregate(name);
|
||||||
monitor.display(client_stats_manager, event.name(), client_id);
|
monitor.display(client_stats_manager, event.name(), client_id)?;
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
}
|
}
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
@ -375,24 +371,24 @@ where
|
|||||||
// TODO: The monitor buffer should be added on client add.
|
// TODO: The monitor buffer should be added on client add.
|
||||||
|
|
||||||
// Get the client for the staterestorer ID
|
// Get the client for the staterestorer ID
|
||||||
client_stats_manager.client_stats_insert(client_id);
|
client_stats_manager.client_stats_insert(client_id)?;
|
||||||
client_stats_manager.update_client_stats_for(client_id, |client| {
|
client_stats_manager.update_client_stats_for(client_id, |client| {
|
||||||
// Update the performance monitor for this client
|
// Update the performance monitor for this client
|
||||||
client.update_introspection_stats((**introspection_stats).clone());
|
client.update_introspection_stats((**introspection_stats).clone());
|
||||||
});
|
})?;
|
||||||
|
|
||||||
// Display the monitor via `.display` only on core #1
|
// Display the monitor via `.display` only on core #1
|
||||||
monitor.display(client_stats_manager, event.name(), client_id);
|
monitor.display(client_stats_manager, event.name(), client_id)?;
|
||||||
|
|
||||||
// Correctly handled the event
|
// Correctly handled the event
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
}
|
}
|
||||||
Event::Objective { objective_size, .. } => {
|
Event::Objective { objective_size, .. } => {
|
||||||
client_stats_manager.client_stats_insert(client_id);
|
client_stats_manager.client_stats_insert(client_id)?;
|
||||||
client_stats_manager.update_client_stats_for(client_id, |client| {
|
client_stats_manager.update_client_stats_for(client_id, |client| {
|
||||||
client.update_objective_size(*objective_size as u64);
|
client.update_objective_size(*objective_size as u64);
|
||||||
});
|
})?;
|
||||||
monitor.display(client_stats_manager, event.name(), client_id);
|
monitor.display(client_stats_manager, event.name(), client_id)?;
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
}
|
}
|
||||||
Event::Log {
|
Event::Log {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Monitors that log to disk using different formats like `JSON` and `TOML`.
|
//! Monitors that log to disk using different formats like `JSON` and `TOML`.
|
||||||
|
|
||||||
use alloc::string::String;
|
use alloc::{string::String, vec::Vec};
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
use std::{
|
use std::{
|
||||||
fs::{File, OpenOptions},
|
fs::{File, OpenOptions},
|
||||||
@ -8,7 +8,7 @@ use std::{
|
|||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
};
|
};
|
||||||
|
|
||||||
use libafl_bolts::{ClientId, current_time};
|
use libafl_bolts::{ClientId, Error, current_time};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::monitors::{Monitor, stats::ClientStatsManager};
|
use crate::monitors::{Monitor, stats::ClientStatsManager};
|
||||||
@ -27,7 +27,7 @@ impl Monitor for OnDiskTomlMonitor {
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
_event_msg: &str,
|
_event_msg: &str,
|
||||||
_sender_id: ClientId,
|
_sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
let cur_time = current_time();
|
let cur_time = current_time();
|
||||||
|
|
||||||
if cur_time - self.last_update >= self.update_interval {
|
if cur_time - self.last_update >= self.update_interval {
|
||||||
@ -57,14 +57,19 @@ exec_sec = {}
|
|||||||
)
|
)
|
||||||
.expect("Failed to write to the Toml file");
|
.expect("Failed to write to the Toml file");
|
||||||
|
|
||||||
for i in 0..(client_stats_manager.client_stats().len()) {
|
let all_clients: Vec<ClientId> = client_stats_manager
|
||||||
let client_id = ClientId(i as u32);
|
.client_stats()
|
||||||
let exec_sec = client_stats_manager
|
.keys()
|
||||||
.update_client_stats_for(client_id, |client_stat| {
|
.copied()
|
||||||
client_stat.execs_per_sec(cur_time)
|
.collect();
|
||||||
});
|
|
||||||
|
|
||||||
let client = client_stats_manager.client_stats_for(client_id);
|
for client_id in &all_clients {
|
||||||
|
let exec_sec = client_stats_manager
|
||||||
|
.update_client_stats_for(*client_id, |client_stat| {
|
||||||
|
client_stat.execs_per_sec(cur_time)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let client = client_stats_manager.client_stats_for(*client_id)?;
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
&mut file,
|
&mut file,
|
||||||
@ -75,7 +80,7 @@ objectives = {}
|
|||||||
executions = {}
|
executions = {}
|
||||||
exec_sec = {}
|
exec_sec = {}
|
||||||
",
|
",
|
||||||
i,
|
client_id.0,
|
||||||
client.corpus_size(),
|
client.corpus_size(),
|
||||||
client.objective_size(),
|
client.objective_size(),
|
||||||
client.executions(),
|
client.executions(),
|
||||||
@ -96,6 +101,7 @@ exec_sec = {}
|
|||||||
|
|
||||||
drop(file);
|
drop(file);
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +176,7 @@ where
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
_event_msg: &str,
|
_event_msg: &str,
|
||||||
_sender_id: ClientId,
|
_sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
if (self.log_record)(client_stats_manager) {
|
if (self.log_record)(client_stats_manager) {
|
||||||
let file = OpenOptions::new()
|
let file = OpenOptions::new()
|
||||||
.append(true)
|
.append(true)
|
||||||
@ -190,5 +196,6 @@ where
|
|||||||
});
|
});
|
||||||
writeln!(&file, "{line}").expect("Unable to write Json to file");
|
writeln!(&file, "{line}").expect("Unable to write Json to file");
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use core::{
|
|||||||
};
|
};
|
||||||
use std::{fs::OpenOptions, io::Write, path::PathBuf};
|
use std::{fs::OpenOptions, io::Write, path::PathBuf};
|
||||||
|
|
||||||
use libafl_bolts::{ClientId, current_time};
|
use libafl_bolts::{ClientId, Error, current_time};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::monitors::{Monitor, stats::ClientStatsManager};
|
use crate::monitors::{Monitor, stats::ClientStatsManager};
|
||||||
@ -35,7 +35,7 @@ impl Monitor for OnDiskJsonAggregateMonitor {
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
_event_msg: &str,
|
_event_msg: &str,
|
||||||
_sender_id: ClientId,
|
_sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
// Write JSON stats if update interval has elapsed
|
// Write JSON stats if update interval has elapsed
|
||||||
let cur_time = current_time();
|
let cur_time = current_time();
|
||||||
if cur_time - self.last_update >= self.update_interval {
|
if cur_time - self.last_update >= self.update_interval {
|
||||||
@ -69,6 +69,7 @@ impl Monitor for OnDiskJsonAggregateMonitor {
|
|||||||
|
|
||||||
writeln!(&file, "{json_value}").expect("Unable to write JSON to file");
|
writeln!(&file, "{json_value}").expect("Unable to write JSON to file");
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Monitor wrappers that add logics to monitor
|
//! Monitor wrappers that add logics to monitor
|
||||||
|
|
||||||
use libafl_bolts::ClientId;
|
use libafl_bolts::{ClientId, Error};
|
||||||
|
|
||||||
use crate::monitors::{Monitor, stats::ClientStatsManager};
|
use crate::monitors::{Monitor, stats::ClientStatsManager};
|
||||||
|
|
||||||
@ -21,11 +21,12 @@ where
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
event_msg: &str,
|
event_msg: &str,
|
||||||
sender_id: ClientId,
|
sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
while (self.closure)(client_stats_manager, event_msg, sender_id) {
|
while (self.closure)(client_stats_manager, event_msg, sender_id) {
|
||||||
self.monitor
|
self.monitor
|
||||||
.display(client_stats_manager, event_msg, sender_id);
|
.display(client_stats_manager, event_msg, sender_id)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,11 +61,12 @@ where
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
event_msg: &str,
|
event_msg: &str,
|
||||||
sender_id: ClientId,
|
sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
if (self.closure)(client_stats_manager, event_msg, sender_id) {
|
if (self.closure)(client_stats_manager, event_msg, sender_id) {
|
||||||
self.monitor
|
self.monitor
|
||||||
.display(client_stats_manager, event_msg, sender_id);
|
.display(client_stats_manager, event_msg, sender_id)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,14 +103,15 @@ where
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
event_msg: &str,
|
event_msg: &str,
|
||||||
sender_id: ClientId,
|
sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
if (self.closure)(client_stats_manager, event_msg, sender_id) {
|
if (self.closure)(client_stats_manager, event_msg, sender_id) {
|
||||||
self.if_monitor
|
self.if_monitor
|
||||||
.display(client_stats_manager, event_msg, sender_id);
|
.display(client_stats_manager, event_msg, sender_id)?;
|
||||||
} else {
|
} else {
|
||||||
self.else_monitor
|
self.else_monitor
|
||||||
.display(client_stats_manager, event_msg, sender_id);
|
.display(client_stats_manager, event_msg, sender_id)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,10 +149,11 @@ where
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
event_msg: &str,
|
event_msg: &str,
|
||||||
sender_id: ClientId,
|
sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
if let Some(monitor) = self.monitor.as_mut() {
|
if let Some(monitor) = self.monitor.as_mut() {
|
||||||
monitor.display(client_stats_manager, event_msg, sender_id);
|
monitor.display(client_stats_manager, event_msg, sender_id)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
//! Keep stats, and display them to the user. Usually used in a broker, or main node, of some sort.
|
//! Keep stats, and display them to the user. Usually used in a broker, or main node, of some sort.
|
||||||
|
|
||||||
pub mod multi;
|
pub mod multi;
|
||||||
|
use libafl_bolts::Error;
|
||||||
pub use multi::MultiMonitor;
|
pub use multi::MultiMonitor;
|
||||||
|
|
||||||
pub mod stats;
|
pub mod stats;
|
||||||
|
|
||||||
pub mod logics;
|
pub mod logics;
|
||||||
@ -53,7 +53,7 @@ pub trait Monitor {
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
event_msg: &str,
|
event_msg: &str,
|
||||||
sender_id: ClientId,
|
sender_id: ClientId,
|
||||||
);
|
) -> Result<(), Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Monitor that print exactly nothing.
|
/// Monitor that print exactly nothing.
|
||||||
@ -68,7 +68,8 @@ impl Monitor for NopMonitor {
|
|||||||
_client_stats_manager: &mut ClientStatsManager,
|
_client_stats_manager: &mut ClientStatsManager,
|
||||||
_event_msg: &str,
|
_event_msg: &str,
|
||||||
_sender_id: ClientId,
|
_sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,8 +108,9 @@ impl Monitor for SimplePrintingMonitor {
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
event_msg: &str,
|
event_msg: &str,
|
||||||
sender_id: ClientId,
|
sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
let mut userstats = client_stats_manager.client_stats()[sender_id.0 as usize]
|
let mut userstats = client_stats_manager
|
||||||
|
.get(sender_id)?
|
||||||
.user_stats()
|
.user_stats()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(key, value)| format!("{key}: {value}"))
|
.map(|(key, value)| format!("{key}: {value}"))
|
||||||
@ -135,11 +137,12 @@ impl Monitor for SimplePrintingMonitor {
|
|||||||
println!(
|
println!(
|
||||||
"Client {:03}:\n{}",
|
"Client {:03}:\n{}",
|
||||||
sender_id.0,
|
sender_id.0,
|
||||||
client_stats_manager.client_stats()[sender_id.0 as usize].introspection_stats
|
client_stats_manager.get(sender_id)?.introspection_stats
|
||||||
);
|
);
|
||||||
// Separate the spacing just a bit
|
// Separate the spacing just a bit
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +174,7 @@ where
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
event_msg: &str,
|
event_msg: &str,
|
||||||
sender_id: ClientId,
|
sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
let global_stats = client_stats_manager.global_stats();
|
let global_stats = client_stats_manager.global_stats();
|
||||||
let mut fmt = format!(
|
let mut fmt = format!(
|
||||||
"[{} #{}] run time: {}, clients: {}, corpus: {}, objectives: {}, executions: {}, exec/sec: {}",
|
"[{} #{}] run time: {}, clients: {}, corpus: {}, objectives: {}, executions: {}, exec/sec: {}",
|
||||||
@ -186,8 +189,8 @@ where
|
|||||||
);
|
);
|
||||||
|
|
||||||
if self.print_user_monitor {
|
if self.print_user_monitor {
|
||||||
client_stats_manager.client_stats_insert(sender_id);
|
client_stats_manager.client_stats_insert(sender_id)?;
|
||||||
let client = client_stats_manager.client_stats_for(sender_id);
|
let client = client_stats_manager.client_stats_for(sender_id)?;
|
||||||
for (key, val) in client.user_stats() {
|
for (key, val) in client.user_stats() {
|
||||||
write!(fmt, ", {key}: {val}").unwrap();
|
write!(fmt, ", {key}: {val}").unwrap();
|
||||||
}
|
}
|
||||||
@ -202,13 +205,14 @@ where
|
|||||||
let fmt = format!(
|
let fmt = format!(
|
||||||
"Client {:03}:\n{}",
|
"Client {:03}:\n{}",
|
||||||
sender_id.0,
|
sender_id.0,
|
||||||
client_stats_manager.client_stats()[sender_id.0 as usize].introspection_stats
|
client_stats_manager.get(sender_id)?.introspection_stats
|
||||||
);
|
);
|
||||||
(self.print_fn)(&fmt);
|
(self.print_fn)(&fmt);
|
||||||
|
|
||||||
// Separate the spacing just a bit
|
// Separate the spacing just a bit
|
||||||
(self.print_fn)("");
|
(self.print_fn)("");
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,9 +282,9 @@ impl<A: Monitor, B: Monitor> Monitor for (A, B) {
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
event_msg: &str,
|
event_msg: &str,
|
||||||
sender_id: ClientId,
|
sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
self.0.display(client_stats_manager, event_msg, sender_id);
|
self.0.display(client_stats_manager, event_msg, sender_id)?;
|
||||||
self.1.display(client_stats_manager, event_msg, sender_id);
|
self.1.display(client_stats_manager, event_msg, sender_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,8 +294,8 @@ impl<A: Monitor> Monitor for (A, ()) {
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
event_msg: &str,
|
event_msg: &str,
|
||||||
sender_id: ClientId,
|
sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
self.0.display(client_stats_manager, event_msg, sender_id);
|
self.0.display(client_stats_manager, event_msg, sender_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,6 +321,6 @@ mod test {
|
|||||||
NopMonitor::default(),
|
NopMonitor::default(),
|
||||||
NopMonitor::default(),
|
NopMonitor::default(),
|
||||||
);
|
);
|
||||||
mgr_list.display(&mut client_stats, "test", ClientId(0));
|
let _ = mgr_list.display(&mut client_stats, "test", ClientId(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use core::{
|
|||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use libafl_bolts::{ClientId, current_time};
|
use libafl_bolts::{ClientId, Error, current_time};
|
||||||
|
|
||||||
use crate::monitors::{Monitor, stats::ClientStatsManager};
|
use crate::monitors::{Monitor, stats::ClientStatsManager};
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ where
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
event_msg: &str,
|
event_msg: &str,
|
||||||
sender_id: ClientId,
|
sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
let sender = format!("#{}", sender_id.0);
|
let sender = format!("#{}", sender_id.0);
|
||||||
let pad = if event_msg.len() + sender.len() < 13 {
|
let pad = if event_msg.len() + sender.len() < 13 {
|
||||||
" ".repeat(13 - event_msg.len() - sender.len())
|
" ".repeat(13 - event_msg.len() - sender.len())
|
||||||
@ -62,11 +62,11 @@ where
|
|||||||
|
|
||||||
(self.print_fn)(&global_fmt);
|
(self.print_fn)(&global_fmt);
|
||||||
|
|
||||||
client_stats_manager.client_stats_insert(sender_id);
|
client_stats_manager.client_stats_insert(sender_id)?;
|
||||||
let cur_time = current_time();
|
let cur_time = current_time();
|
||||||
let exec_sec = client_stats_manager
|
let exec_sec = client_stats_manager
|
||||||
.update_client_stats_for(sender_id, |client| client.execs_per_sec_pretty(cur_time));
|
.update_client_stats_for(sender_id, |client| client.execs_per_sec_pretty(cur_time))?;
|
||||||
let client = client_stats_manager.client_stats_for(sender_id);
|
let client = client_stats_manager.client_stats_for(sender_id)?;
|
||||||
|
|
||||||
let pad = " ".repeat(head.len());
|
let pad = " ".repeat(head.len());
|
||||||
let mut fmt = format!(
|
let mut fmt = format!(
|
||||||
@ -86,10 +86,10 @@ where
|
|||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
{
|
{
|
||||||
// Print the client performance monitor. Skip the Client 0 which is the broker
|
// Print the client performance monitor. Skip the Client 0 which is the broker
|
||||||
for (i, client) in client_stats_manager
|
for (i, (_, client)) in client_stats_manager
|
||||||
.client_stats()
|
.client_stats()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|x| x.enabled())
|
.filter(|(_, x)| x.enabled())
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
let fmt = format!("Client {:03}:\n{}", i + 1, client.introspection_stats);
|
let fmt = format!("Client {:03}:\n{}", i + 1, client.introspection_stats);
|
||||||
@ -99,6 +99,7 @@ where
|
|||||||
// Separate the spacing just a bit
|
// Separate the spacing just a bit
|
||||||
(self.print_fn)("\n");
|
(self.print_fn)("\n");
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ use std::thread;
|
|||||||
|
|
||||||
// using thread in order to start the HTTP server in a separate thread
|
// using thread in order to start the HTTP server in a separate thread
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
use libafl_bolts::{ClientId, current_time};
|
use libafl_bolts::{ClientId, Error, current_time};
|
||||||
// using the official rust client library for Prometheus: https://github.com/prometheus/client_rust
|
// using the official rust client library for Prometheus: https://github.com/prometheus/client_rust
|
||||||
use prometheus_client::{
|
use prometheus_client::{
|
||||||
encoding::{EncodeLabelSet, text::encode},
|
encoding::{EncodeLabelSet, text::encode},
|
||||||
@ -98,7 +98,7 @@ where
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
event_msg: &str,
|
event_msg: &str,
|
||||||
sender_id: ClientId,
|
sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
// Update the prometheus metrics
|
// Update the prometheus metrics
|
||||||
// The gauges must take signed i64's, with max value of 2^63-1 so it is
|
// The gauges must take signed i64's, with max value of 2^63-1 so it is
|
||||||
// probably fair to error out at a count of nine quintillion across any
|
// probably fair to error out at a count of nine quintillion across any
|
||||||
@ -216,8 +216,8 @@ where
|
|||||||
|
|
||||||
// Client-specific metrics
|
// Client-specific metrics
|
||||||
|
|
||||||
client_stats_manager.client_stats_insert(sender_id);
|
client_stats_manager.client_stats_insert(sender_id)?;
|
||||||
let client = client_stats_manager.client_stats_for(sender_id);
|
let client = client_stats_manager.client_stats_for(sender_id)?;
|
||||||
let mut cur_client_clone = client.clone();
|
let mut cur_client_clone = client.clone();
|
||||||
|
|
||||||
self.prometheus_client_stats
|
self.prometheus_client_stats
|
||||||
@ -319,6 +319,7 @@ where
|
|||||||
.set(value);
|
.set(value);
|
||||||
}
|
}
|
||||||
(self.print_fn)(&fmt);
|
(self.print_fn)(&fmt);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
use alloc::{borrow::Cow, string::String, vec::Vec};
|
use alloc::{borrow::Cow, string::String};
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libafl_bolts::{ClientId, current_time, format_duration_hms};
|
use libafl_bolts::{ClientId, Error, current_time, format_duration_hms};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ use super::{
|
|||||||
/// Manager of all client's statistics
|
/// Manager of all client's statistics
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ClientStatsManager {
|
pub struct ClientStatsManager {
|
||||||
client_stats: Vec<ClientStats>,
|
client_stats: HashMap<ClientId, ClientStats>,
|
||||||
/// Aggregated user stats value.
|
/// Aggregated user stats value.
|
||||||
///
|
///
|
||||||
/// This map is updated by event manager, and is read by monitors to display user-defined stats.
|
/// This map is updated by event manager, and is read by monitors to display user-defined stats.
|
||||||
@ -37,7 +37,7 @@ impl ClientStatsManager {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
client_stats: vec![],
|
client_stats: HashMap::new(),
|
||||||
cached_aggregated_user_stats: HashMap::new(),
|
cached_aggregated_user_stats: HashMap::new(),
|
||||||
cached_global_stats: None,
|
cached_global_stats: None,
|
||||||
start_time: current_time(),
|
start_time: current_time(),
|
||||||
@ -46,25 +46,31 @@ impl ClientStatsManager {
|
|||||||
|
|
||||||
/// Get all client stats
|
/// Get all client stats
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn client_stats(&self) -> &[ClientStats] {
|
pub fn client_stats(&self) -> &HashMap<ClientId, ClientStats> {
|
||||||
&self.client_stats
|
&self.client_stats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get client with `client_id`
|
||||||
|
pub fn get(&self, client_id: ClientId) -> Result<&ClientStats, Error> {
|
||||||
|
self.client_stats
|
||||||
|
.get(&client_id)
|
||||||
|
.ok_or_else(|| Error::key_not_found(format!("Client id {client_id:#?} not found")))
|
||||||
|
}
|
||||||
|
|
||||||
/// The client monitor for a specific id, creating new if it doesn't exist
|
/// The client monitor for a specific id, creating new if it doesn't exist
|
||||||
pub fn client_stats_insert(&mut self, client_id: ClientId) {
|
pub fn client_stats_insert(&mut self, client_id: ClientId) -> Result<(), Error> {
|
||||||
let total_client_stat_count = self.client_stats().len();
|
// if it doesn't contain this new client then insert it
|
||||||
for _ in total_client_stat_count..=(client_id.0) as usize {
|
if !self.client_stats.contains_key(&client_id) {
|
||||||
self.client_stats.push(ClientStats {
|
let stats = ClientStats {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
last_window_time: Duration::from_secs(0),
|
last_window_time: Duration::from_secs(0),
|
||||||
start_time: Duration::from_secs(0),
|
start_time: Duration::from_secs(0),
|
||||||
..ClientStats::default()
|
..ClientStats::default()
|
||||||
});
|
};
|
||||||
}
|
self.client_stats.insert(client_id, stats);
|
||||||
if total_client_stat_count <= client_id.0 as usize {
|
|
||||||
// The client count changed!
|
|
||||||
self.cached_global_stats = None;
|
self.cached_global_stats = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update_client_stats_for(client_id, |new_stat| {
|
self.update_client_stats_for(client_id, |new_stat| {
|
||||||
if !new_stat.enabled {
|
if !new_stat.enabled {
|
||||||
let timestamp = current_time();
|
let timestamp = current_time();
|
||||||
@ -74,7 +80,8 @@ impl ClientStatsManager {
|
|||||||
new_stat.enabled = true;
|
new_stat.enabled = true;
|
||||||
new_stat.stats_status.basic_stats_updated = true;
|
new_stat.stats_status.basic_stats_updated = true;
|
||||||
}
|
}
|
||||||
});
|
})?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update sepecific client stats.
|
/// Update sepecific client stats.
|
||||||
@ -84,28 +91,34 @@ impl ClientStatsManager {
|
|||||||
&mut self,
|
&mut self,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
update: F,
|
update: F,
|
||||||
) -> T {
|
) -> Result<T, Error> {
|
||||||
let client_stat = &mut self.client_stats[client_id.0 as usize];
|
if let Some(stat) = self.client_stats.get_mut(&client_id) {
|
||||||
client_stat.clear_stats_status();
|
stat.clear_stats_status();
|
||||||
let res = update(client_stat);
|
let res = update(stat);
|
||||||
if client_stat.stats_status.basic_stats_updated {
|
if stat.stats_status.basic_stats_updated {
|
||||||
self.cached_global_stats = None;
|
self.cached_global_stats = None;
|
||||||
}
|
}
|
||||||
res
|
Ok(res)
|
||||||
|
} else {
|
||||||
|
Err(Error::key_not_found(format!(
|
||||||
|
"Client id {client_id:#?} not found!"
|
||||||
|
)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update all client stats. This will clear all previous client stats, and fill in the new client stats.
|
/// Update all client stats. This will clear all previous client stats, and fill in the new client stats.
|
||||||
///
|
///
|
||||||
/// This will clear global stats cache.
|
/// This will clear global stats cache.
|
||||||
pub fn update_all_client_stats(&mut self, new_client_stats: Vec<ClientStats>) {
|
pub fn update_all_client_stats(&mut self, new_client_stats: HashMap<ClientId, ClientStats>) {
|
||||||
self.client_stats = new_client_stats;
|
self.client_stats = new_client_stats;
|
||||||
self.cached_global_stats = None;
|
self.cached_global_stats = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get immutable reference to client stats
|
/// Get immutable reference to client stats
|
||||||
#[must_use]
|
pub fn client_stats_for(&self, client_id: ClientId) -> Result<&ClientStats, Error> {
|
||||||
pub fn client_stats_for(&self, client_id: ClientId) -> &ClientStats {
|
self.client_stats
|
||||||
&self.client_stats()[client_id.0 as usize]
|
.get(&client_id)
|
||||||
|
.ok_or_else(|| Error::key_not_found(format!("Client id {client_id:#?} not found")))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Aggregate user-defined stats
|
/// Aggregate user-defined stats
|
||||||
@ -138,20 +151,20 @@ impl ClientStatsManager {
|
|||||||
client_stats_count: self
|
client_stats_count: self
|
||||||
.client_stats
|
.client_stats
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|client| client.enabled)
|
.filter(|(_, client)| client.enabled)
|
||||||
.count(),
|
.count(),
|
||||||
corpus_size: self
|
corpus_size: self
|
||||||
.client_stats
|
.client_stats
|
||||||
.iter()
|
.iter()
|
||||||
.fold(0_u64, |acc, x| acc + x.corpus_size),
|
.fold(0_u64, |acc, (_, client)| acc + client.corpus_size),
|
||||||
objective_size: self
|
objective_size: self
|
||||||
.client_stats
|
.client_stats
|
||||||
.iter()
|
.iter()
|
||||||
.fold(0_u64, |acc, x| acc + x.objective_size),
|
.fold(0_u64, |acc, (_, client)| acc + client.objective_size),
|
||||||
total_execs: self
|
total_execs: self
|
||||||
.client_stats
|
.client_stats
|
||||||
.iter()
|
.iter()
|
||||||
.fold(0_u64, |acc, x| acc + x.executions),
|
.fold(0_u64, |acc, (_, client)| acc + client.executions),
|
||||||
..GlobalStats::default()
|
..GlobalStats::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -162,7 +175,7 @@ impl ClientStatsManager {
|
|||||||
global_stats.execs_per_sec = self
|
global_stats.execs_per_sec = self
|
||||||
.client_stats
|
.client_stats
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.fold(0.0, |acc, x| acc + x.execs_per_sec(cur_time));
|
.fold(0.0, |acc, (_, client)| acc + client.execs_per_sec(cur_time));
|
||||||
global_stats.execs_per_sec_pretty = super::prettify_float(global_stats.execs_per_sec);
|
global_stats.execs_per_sec_pretty = super::prettify_float(global_stats.execs_per_sec);
|
||||||
|
|
||||||
global_stats
|
global_stats
|
||||||
@ -177,9 +190,13 @@ impl ClientStatsManager {
|
|||||||
if self.client_stats().len() > 1 {
|
if self.client_stats().len() > 1 {
|
||||||
let mut new_path_time = Duration::default();
|
let mut new_path_time = Duration::default();
|
||||||
let mut new_objectives_time = Duration::default();
|
let mut new_objectives_time = Duration::default();
|
||||||
for client in self.client_stats().iter().filter(|client| client.enabled()) {
|
for (_, stat) in self
|
||||||
new_path_time = client.last_corpus_time().max(new_path_time);
|
.client_stats()
|
||||||
new_objectives_time = client.last_objective_time().max(new_objectives_time);
|
.iter()
|
||||||
|
.filter(|(_, client)| client.enabled())
|
||||||
|
{
|
||||||
|
new_path_time = stat.last_corpus_time().max(new_path_time);
|
||||||
|
new_objectives_time = stat.last_objective_time().max(new_objectives_time);
|
||||||
}
|
}
|
||||||
if new_path_time > self.start_time() {
|
if new_path_time > self.start_time() {
|
||||||
total_process_timing.last_new_entry = new_path_time - self.start_time();
|
total_process_timing.last_new_entry = new_path_time - self.start_time();
|
||||||
@ -196,7 +213,8 @@ impl ClientStatsManager {
|
|||||||
pub fn edges_coverage(&self) -> Option<EdgeCoverage> {
|
pub fn edges_coverage(&self) -> Option<EdgeCoverage> {
|
||||||
self.client_stats()
|
self.client_stats()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|client| client.enabled())
|
.filter(|(_, client)| client.enabled())
|
||||||
|
.map(|(_, client)| client)
|
||||||
.filter_map(ClientStats::edges_coverage)
|
.filter_map(ClientStats::edges_coverage)
|
||||||
.max_by_key(
|
.max_by_key(
|
||||||
|EdgeCoverage {
|
|EdgeCoverage {
|
||||||
@ -217,7 +235,11 @@ impl ClientStatsManager {
|
|||||||
}
|
}
|
||||||
let mut ratio_a: u64 = 0;
|
let mut ratio_a: u64 = 0;
|
||||||
let mut ratio_b: u64 = 0;
|
let mut ratio_b: u64 = 0;
|
||||||
for client in self.client_stats().iter().filter(|client| client.enabled()) {
|
for (_, client) in self
|
||||||
|
.client_stats()
|
||||||
|
.iter()
|
||||||
|
.filter(|(_, client)| client.enabled())
|
||||||
|
{
|
||||||
let afl_stats = client
|
let afl_stats = client
|
||||||
.get_user_stats("AflStats")
|
.get_user_stats("AflStats")
|
||||||
.map_or("None".to_string(), ToString::to_string);
|
.map_or("None".to_string(), ToString::to_string);
|
||||||
|
@ -69,7 +69,7 @@ pub(super) fn aggregate_user_stats(
|
|||||||
let mut gather = client_stats_manager
|
let mut gather = client_stats_manager
|
||||||
.client_stats()
|
.client_stats()
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|client| client.user_stats.get(name.as_ref()));
|
.filter_map(|(_, client)| client.user_stats.get(name.as_ref()));
|
||||||
|
|
||||||
let gather_count = gather.clone().count();
|
let gather_count = gather.clone().count();
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ use alloc::{borrow::Cow, string::String, vec::Vec};
|
|||||||
use std::net::UdpSocket;
|
use std::net::UdpSocket;
|
||||||
|
|
||||||
use cadence::{BufferedUdpMetricSink, Gauged, QueuingMetricSink, StatsdClient};
|
use cadence::{BufferedUdpMetricSink, Gauged, QueuingMetricSink, StatsdClient};
|
||||||
use libafl_bolts::ClientId;
|
use libafl_bolts::{ClientId, Error};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Monitor,
|
Monitor,
|
||||||
@ -194,7 +194,7 @@ impl Monitor for StatsdMonitor {
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
_event_msg: &str,
|
_event_msg: &str,
|
||||||
_sender_id: ClientId,
|
_sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
if self.try_display(client_stats_manager).is_none() {
|
if self.try_display(client_stats_manager).is_none() {
|
||||||
// The client failed to send metrics, which means the server is down
|
// The client failed to send metrics, which means the server is down
|
||||||
// or something else happened. We then de-initialize the client, and
|
// or something else happened. We then de-initialize the client, and
|
||||||
@ -202,5 +202,6 @@ impl Monitor for StatsdMonitor {
|
|||||||
// and try to connect the server then.
|
// and try to connect the server then.
|
||||||
self.statsd_client = None;
|
self.statsd_client = None;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ use crossterm::{
|
|||||||
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
|
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
|
||||||
};
|
};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libafl_bolts::{ClientId, current_time, format_big_number, format_duration_hms};
|
use libafl_bolts::{ClientId, Error, current_time, format_big_number, format_duration_hms};
|
||||||
use ratatui::{Terminal, backend::CrosstermBackend};
|
use ratatui::{Terminal, backend::CrosstermBackend};
|
||||||
use typed_builder::TypedBuilder;
|
use typed_builder::TypedBuilder;
|
||||||
|
|
||||||
@ -341,7 +341,7 @@ impl Monitor for TuiMonitor {
|
|||||||
client_stats_manager: &mut ClientStatsManager,
|
client_stats_manager: &mut ClientStatsManager,
|
||||||
event_msg: &str,
|
event_msg: &str,
|
||||||
sender_id: ClientId,
|
sender_id: ClientId,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
let cur_time = current_time();
|
let cur_time = current_time();
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -378,10 +378,10 @@ impl Monitor for TuiMonitor {
|
|||||||
ctx.total_item_geometry = client_stats_manager.item_geometry();
|
ctx.total_item_geometry = client_stats_manager.item_geometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
client_stats_manager.client_stats_insert(sender_id);
|
client_stats_manager.client_stats_insert(sender_id)?;
|
||||||
let exec_sec = client_stats_manager
|
let exec_sec = client_stats_manager
|
||||||
.update_client_stats_for(sender_id, |client| client.execs_per_sec_pretty(cur_time));
|
.update_client_stats_for(sender_id, |client| client.execs_per_sec_pretty(cur_time))?;
|
||||||
let client = client_stats_manager.client_stats_for(sender_id);
|
let client = client_stats_manager.client_stats_for(sender_id)?;
|
||||||
|
|
||||||
let sender = format!("#{}", sender_id.0);
|
let sender = format!("#{}", sender_id.0);
|
||||||
let pad = if event_msg.len() + sender.len() < 13 {
|
let pad = if event_msg.len() + sender.len() < 13 {
|
||||||
@ -412,7 +412,7 @@ impl Monitor for TuiMonitor {
|
|||||||
.entry(sender_id.0 as usize)
|
.entry(sender_id.0 as usize)
|
||||||
.or_default()
|
.or_default()
|
||||||
.grab_data(client);
|
.grab_data(client);
|
||||||
});
|
})?;
|
||||||
while ctx.client_logs.len() >= DEFAULT_LOGS_NUMBER {
|
while ctx.client_logs.len() >= DEFAULT_LOGS_NUMBER {
|
||||||
ctx.client_logs.pop_front();
|
ctx.client_logs.pop_front();
|
||||||
}
|
}
|
||||||
@ -422,10 +422,10 @@ impl Monitor for TuiMonitor {
|
|||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
{
|
{
|
||||||
// Print the client performance monitor. Skip the Client IDs that have never sent anything.
|
// Print the client performance monitor. Skip the Client IDs that have never sent anything.
|
||||||
for (i, client) in client_stats_manager
|
for (i, (_, client)) in client_stats_manager
|
||||||
.client_stats()
|
.client_stats()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|x| x.enabled())
|
.filter(|(_, x)| x.enabled())
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
self.context
|
self.context
|
||||||
@ -437,6 +437,8 @@ impl Monitor for TuiMonitor {
|
|||||||
.grab_data(&client.introspection_stats);
|
.grab_data(&client.introspection_stats);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ fn generate_mutations(iter: impl Iterator<Item = (SymExprRef, SymExpr)>) -> Vec<
|
|||||||
res.push(replacements);
|
res.push(replacements);
|
||||||
solver.pop(1);
|
solver.pop(1);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
// assert the path constraint
|
// assert the path constraint
|
||||||
solver.assert(&op);
|
solver.assert(&op);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
use core::str::FromStr;
|
||||||
use std::{
|
use std::{
|
||||||
env, fs,
|
env, fs,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::Command,
|
process::Command,
|
||||||
str::FromStr,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use which::which;
|
use which::which;
|
||||||
|
@ -23,6 +23,7 @@ run_clippy() {
|
|||||||
# Define projects based on the operating system
|
# Define projects based on the operating system
|
||||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||||
ALL_PROJECTS=(
|
ALL_PROJECTS=(
|
||||||
|
"libafl"
|
||||||
"libafl_bolts"
|
"libafl_bolts"
|
||||||
"libafl_cc"
|
"libafl_cc"
|
||||||
"libafl_concolic/symcc_runtime"
|
"libafl_concolic/symcc_runtime"
|
||||||
@ -52,17 +53,16 @@ else
|
|||||||
IFS=',' read -ra PROJECTS <<<"$1"
|
IFS=',' read -ra PROJECTS <<<"$1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# First run it on all
|
|
||||||
eval "$CLIPPY_CMD --workspace -- $RUSTC_FLAGS"
|
|
||||||
|
|
||||||
# Loop through each project and run Clippy
|
# Loop through each project and run Clippy
|
||||||
for project in "${PROJECTS[@]}"; do
|
for project in "${PROJECTS[@]}"; do
|
||||||
# Trim leading and trailing whitespace
|
# Trim leading and trailing whitespace
|
||||||
project=$(echo "$project" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
project=$(echo "$project" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
features="--all-features"
|
features="--all-features"
|
||||||
if [[ " ${NO_ALL_FEATURES[*]} " =~ ${project} ]]; then
|
for item in "${NO_ALL_FEATURES[@]}"; do
|
||||||
|
if [[ "$item" == "$project" ]]; then
|
||||||
features="--features=clippy"
|
features="--features=clippy"
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
if [ -d "$project" ]; then
|
if [ -d "$project" ]; then
|
||||||
run_clippy "$project" "$features"
|
run_clippy "$project" "$features"
|
||||||
else
|
else
|
||||||
@ -71,3 +71,6 @@ for project in "${PROJECTS[@]}"; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
echo "Clippy run completed for all specified projects."
|
echo "Clippy run completed for all specified projects."
|
||||||
|
|
||||||
|
# Last run it on all
|
||||||
|
eval "$CLIPPY_CMD --workspace -- $RUSTC_FLAGS"
|
Loading…
x
Reference in New Issue
Block a user