Less useless allocs for monitor display (#1874)

* Less useless allocs for monitor display

* More less String

* Lol who needs generics

* clippy

* remove &String
This commit is contained in:
Dominik Maier 2024-02-19 21:15:11 +01:00 committed by GitHub
parent f48e281be8
commit 263af87652
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 73 additions and 87 deletions

View File

@ -446,7 +446,7 @@ where
fn add_custom_buf_handler(
&mut self,
handler: Box<
dyn FnMut(&mut Self::State, &String, &[u8]) -> Result<CustomBufEventResult, Error>,
dyn FnMut(&mut Self::State, &str, &[u8]) -> Result<CustomBufEventResult, Error>,
>,
) {
self.inner.add_custom_buf_handler(handler);

View File

@ -1,10 +1,6 @@
//! LLMP-backed event manager for scalable multi-processed fuzzing
use alloc::{
boxed::Box,
string::{String, ToString},
vec::Vec,
};
use alloc::{boxed::Box, vec::Vec};
#[cfg(all(unix, not(miri), feature = "std"))]
use core::ptr::addr_of_mut;
#[cfg(feature = "std")]
@ -208,7 +204,7 @@ where
Ok(llmp::LlmpMsgHookResult::ForwardToClients)
}
} else {
monitor.display("Broker".into(), ClientId(0));
monitor.display("Broker", ClientId(0));
Ok(llmp::LlmpMsgHookResult::Handled)
}
},
@ -254,7 +250,7 @@ where
// as a forwarded msg with a lower executions may arrive after a stats msg with an higher executions
client.update_executions(*executions as u64, *time);
}
monitor.display(event.name().to_string(), id);
monitor.display(event.name(), id);
Ok(BrokerEventResult::Forward)
}
Event::UpdateExecStats {
@ -266,7 +262,7 @@ where
monitor.client_stats_insert(client_id);
let client = monitor.client_stats_mut_for(client_id);
client.update_executions(*executions as u64, *time);
monitor.display(event.name().to_string(), client_id);
monitor.display(event.name(), client_id);
Ok(BrokerEventResult::Handled)
}
Event::UpdateUserStats {
@ -278,7 +274,7 @@ where
let client = monitor.client_stats_mut_for(client_id);
client.update_user_stats(name.clone(), value.clone());
monitor.aggregate(name);
monitor.display(event.name().to_string(), client_id);
monitor.display(event.name(), client_id);
Ok(BrokerEventResult::Handled)
}
#[cfg(feature = "introspection")]
@ -301,7 +297,7 @@ where
client.update_introspection_monitor((**introspection_monitor).clone());
// Display the monitor via `.display` only on core #1
monitor.display(event.name().to_string(), client_id);
monitor.display(event.name(), client_id);
// Correctly handled the event
Ok(BrokerEventResult::Handled)
@ -310,7 +306,7 @@ where
monitor.client_stats_insert(client_id);
let client = monitor.client_stats_mut_for(client_id);
client.update_objective_size(*objective_size as u64);
monitor.display(event.name().to_string(), client_id);
monitor.display(event.name(), client_id);
Ok(BrokerEventResult::Handled)
}
Event::Log {
@ -826,7 +822,7 @@ where
{
fn add_custom_buf_handler(
&mut self,
handler: Box<dyn FnMut(&mut S, &String, &[u8]) -> Result<CustomBufEventResult, Error>>,
handler: Box<dyn FnMut(&mut S, &str, &[u8]) -> Result<CustomBufEventResult, Error>>,
) {
self.custom_buf_handlers.push(handler);
}

View File

@ -598,8 +598,7 @@ where
}
/// The handler function for custom buffers exchanged via [`EventManager`]
type CustomBufHandlerFn<S> =
dyn FnMut(&mut S, &String, &[u8]) -> Result<CustomBufEventResult, Error>;
type CustomBufHandlerFn<S> = dyn FnMut(&mut S, &str, &[u8]) -> Result<CustomBufEventResult, Error>;
/// Supports custom buf handlers to handle `CustomBuf` events.
pub trait HasCustomBufHandlers: UsesState {
@ -677,7 +676,7 @@ where
fn add_custom_buf_handler(
&mut self,
_handler: Box<
dyn FnMut(&mut Self::State, &String, &[u8]) -> Result<CustomBufEventResult, Error>,
dyn FnMut(&mut Self::State, &str, &[u8]) -> Result<CustomBufEventResult, Error>,
>,
) {
}
@ -808,7 +807,7 @@ where
fn add_custom_buf_handler(
&mut self,
handler: Box<
dyn FnMut(&mut Self::State, &String, &[u8]) -> Result<CustomBufEventResult, Error>,
dyn FnMut(&mut Self::State, &str, &[u8]) -> Result<CustomBufEventResult, Error>,
>,
) {
self.inner.add_custom_buf_handler(handler);

View File

@ -1,10 +1,6 @@
//! A very simple event manager, that just supports log outputs, but no multiprocessing
use alloc::{
boxed::Box,
string::{String, ToString},
vec::Vec,
};
use alloc::{boxed::Box, vec::Vec};
#[cfg(all(unix, not(miri), feature = "std"))]
use core::ptr::addr_of_mut;
use core::{fmt::Debug, marker::PhantomData};
@ -146,7 +142,7 @@ where
fn add_custom_buf_handler(
&mut self,
handler: Box<
dyn FnMut(&mut Self::State, &String, &[u8]) -> Result<CustomBufEventResult, Error>,
dyn FnMut(&mut Self::State, &str, &[u8]) -> Result<CustomBufEventResult, Error>,
>,
) {
self.custom_buf_handlers.push(handler);
@ -221,7 +217,7 @@ where
monitor
.client_stats_mut_for(ClientId(0))
.update_executions(*executions as u64, *time);
monitor.display(event.name().to_string(), ClientId(0));
monitor.display(event.name(), ClientId(0));
Ok(BrokerEventResult::Handled)
}
Event::UpdateExecStats {
@ -235,7 +231,7 @@ where
client.update_executions(*executions as u64, *time);
monitor.display(event.name().to_string(), ClientId(0));
monitor.display(event.name(), ClientId(0));
Ok(BrokerEventResult::Handled)
}
Event::UpdateUserStats {
@ -248,7 +244,7 @@ where
.client_stats_mut_for(ClientId(0))
.update_user_stats(name.clone(), value.clone());
monitor.aggregate(name);
monitor.display(event.name().to_string(), ClientId(0));
monitor.display(event.name(), ClientId(0));
Ok(BrokerEventResult::Handled)
}
#[cfg(feature = "introspection")]
@ -263,7 +259,7 @@ where
let client = monitor.client_stats_mut_for(ClientId(0));
client.update_executions(*executions as u64, *time);
client.update_introspection_monitor((**introspection_monitor).clone());
monitor.display(event.name().to_string(), ClientId(0));
monitor.display(event.name(), ClientId(0));
Ok(BrokerEventResult::Handled)
}
Event::Objective { objective_size } => {
@ -271,7 +267,7 @@ where
monitor
.client_stats_mut_for(ClientId(0))
.update_objective_size(*objective_size as u64);
monitor.display(event.name().to_string(), ClientId(0));
monitor.display(event.name(), ClientId(0));
Ok(BrokerEventResult::Handled)
}
Event::Log {
@ -407,7 +403,7 @@ where
{
fn add_custom_buf_handler(
&mut self,
handler: Box<dyn FnMut(&mut S, &String, &[u8]) -> Result<CustomBufEventResult, Error>>,
handler: Box<dyn FnMut(&mut S, &str, &[u8]) -> Result<CustomBufEventResult, Error>>,
) {
self.simple_event_mgr.add_custom_buf_handler(handler);
}

View File

@ -1,10 +1,6 @@
//! TCP-backed event manager for scalable multi-processed fuzzing
use alloc::{
boxed::Box,
string::{String, ToString},
vec::Vec,
};
use alloc::{boxed::Box, vec::Vec};
#[cfg(all(unix, feature = "std", not(miri)))]
use core::ptr::addr_of_mut;
use core::{
@ -337,7 +333,7 @@ where
let client = monitor.client_stats_mut_for(id);
client.update_corpus_size(*corpus_size as u64);
client.update_executions(*executions as u64, *time);
monitor.display(event.name().to_string(), id);
monitor.display(event.name(), id);
Ok(BrokerEventResult::Forward)
}
Event::UpdateExecStats {
@ -349,7 +345,7 @@ where
monitor.client_stats_insert(client_id);
let client = monitor.client_stats_mut_for(client_id);
client.update_executions(*executions as u64, *time);
monitor.display(event.name().to_string(), client_id);
monitor.display(event.name(), client_id);
Ok(BrokerEventResult::Handled)
}
Event::UpdateUserStats {
@ -361,7 +357,7 @@ where
let client = monitor.client_stats_mut_for(client_id);
client.update_user_stats(name.clone(), value.clone());
monitor.aggregate(name);
monitor.display(event.name().to_string(), client_id);
monitor.display(event.name(), client_id);
Ok(BrokerEventResult::Handled)
}
#[cfg(feature = "introspection")]
@ -384,7 +380,7 @@ where
client.update_introspection_monitor((**introspection_monitor).clone());
// Display the monitor via `.display` only on core #1
monitor.display(event.name().to_string(), client_id);
monitor.display(event.name(), client_id);
// Correctly handled the event
Ok(BrokerEventResult::Handled)
@ -393,7 +389,7 @@ where
monitor.client_stats_insert(client_id);
let client = monitor.client_stats_mut_for(client_id);
client.update_objective_size(*objective_size as u64);
monitor.display(event.name().to_string(), client_id);
monitor.display(event.name(), client_id);
Ok(BrokerEventResult::Handled)
}
Event::Log {
@ -759,7 +755,7 @@ where
{
fn add_custom_buf_handler(
&mut self,
handler: Box<dyn FnMut(&mut S, &String, &[u8]) -> Result<CustomBufEventResult, Error>>,
handler: Box<dyn FnMut(&mut S, &str, &[u8]) -> Result<CustomBufEventResult, Error>>,
) {
self.custom_buf_handlers.push(handler);
}

View File

@ -52,7 +52,7 @@ where
self.base.aggregate(name);
}
fn display(&mut self, event_msg: String, sender_id: ClientId) {
fn display(&mut self, event_msg: &str, sender_id: ClientId) {
let cur_time = current_time();
if (cur_time - self.last_update).as_secs() >= 60 {
@ -201,7 +201,7 @@ where
self.base.set_start_time(time);
}
fn display(&mut self, event_msg: String, sender_id: ClientId) {
fn display(&mut self, event_msg: &str, sender_id: ClientId) {
if (self.log_record)(&mut self.base) {
let file = OpenOptions::new()
.append(true)

View File

@ -497,7 +497,7 @@ pub trait Monitor {
fn set_start_time(&mut self, time: Duration);
/// Show the monitor to the user
fn display(&mut self, event_msg: String, sender_id: ClientId);
fn display(&mut self, event_msg: &str, sender_id: ClientId);
/// Amount of elements in the corpus (combined for all children)
fn corpus_size(&self) -> u64 {
@ -591,7 +591,8 @@ impl Monitor for NopMonitor {
self.start_time = time;
}
fn display(&mut self, _event_msg: String, _sender_id: ClientId) {}
#[inline]
fn display(&mut self, _event_msg: &str, _sender_id: ClientId) {}
}
impl NopMonitor {
@ -660,7 +661,7 @@ impl Monitor for SimplePrintingMonitor {
self.start_time = time;
}
fn display(&mut self, event_msg: String, sender_id: ClientId) {
fn display(&mut self, event_msg: &str, sender_id: ClientId) {
let mut userstats = self.client_stats()[sender_id.0 as usize]
.user_monitor
.iter()
@ -698,7 +699,7 @@ impl Monitor for SimplePrintingMonitor {
#[derive(Clone)]
pub struct SimpleMonitor<F>
where
F: FnMut(String),
F: FnMut(&str),
{
print_fn: F,
start_time: Duration,
@ -708,7 +709,7 @@ where
impl<F> Debug for SimpleMonitor<F>
where
F: FnMut(String),
F: FnMut(&str),
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SimpleMonitor")
@ -720,7 +721,7 @@ where
impl<F> Monitor for SimpleMonitor<F>
where
F: FnMut(String),
F: FnMut(&str),
{
/// the client monitor, mutable
fn client_stats_mut(&mut self) -> &mut Vec<ClientStats> {
@ -742,7 +743,7 @@ where
self.start_time = time;
}
fn display(&mut self, event_msg: String, sender_id: ClientId) {
fn display(&mut self, event_msg: &str, sender_id: ClientId) {
let mut fmt = format!(
"[{} #{}] run time: {}, clients: {}, corpus: {}, objectives: {}, executions: {}, exec/sec: {}",
event_msg,
@ -763,7 +764,7 @@ where
}
}
(self.print_fn)(fmt);
(self.print_fn)(&fmt);
// Only print perf monitor if the feature is enabled
#[cfg(feature = "introspection")]
@ -773,17 +774,17 @@ where
"Client {:03}:\n{}",
sender_id.0, self.client_stats[sender_id.0 as usize].introspection_monitor
);
(self.print_fn)(fmt);
(self.print_fn)(&fmt);
// Separate the spacing just a bit
(self.print_fn)(String::new());
(self.print_fn)("");
}
}
}
impl<F> SimpleMonitor<F>
where
F: FnMut(String),
F: FnMut(&str),
{
/// Creates the monitor, using the `current_time` as `start_time`.
pub fn new(print_fn: F) -> Self {
@ -1293,7 +1294,7 @@ impl Default for ClientPerfMonitor {
#[allow(clippy::unnecessary_fallible_conversions)]
#[allow(missing_docs)]
pub mod pybind {
use alloc::{boxed::Box, string::String, vec::Vec};
use alloc::{boxed::Box, vec::Vec};
use core::time::Duration;
use libafl_bolts::ClientId;
@ -1302,13 +1303,16 @@ pub mod pybind {
use super::ClientStats;
use crate::monitors::{Monitor, SimpleMonitor};
/// A [`SimpleMonitor`] type with a boxed `FnMut` for printing
pub type SimpleBoxedFnMonitor = SimpleMonitor<Box<dyn FnMut(&str)>>;
// TODO create a PyObjectFnMut to pass, track stabilization of https://github.com/rust-lang/rust/issues/29625
#[pyclass(unsendable, name = "SimpleMonitor")]
/// Python class for SimpleMonitor
pub struct PythonSimpleMonitor {
/// Rust wrapped SimpleMonitor object
pub inner: SimpleMonitor<Box<dyn FnMut(String)>>,
pub inner: SimpleBoxedFnMonitor,
print_fn: PyObject,
}
@ -1323,9 +1327,9 @@ pub mod pybind {
impl Clone for PythonSimpleMonitor {
fn clone(&self) -> PythonSimpleMonitor {
let py_print_fn = self.print_fn.clone();
let closure = move |s: String| {
let closure = move |s: &str| {
Python::with_gil(|py| -> PyResult<()> {
py_print_fn.call1(py, (PyUnicode::new(py, &s),))?;
py_print_fn.call1(py, (PyUnicode::new(py, s),))?;
Ok(())
})
.unwrap();
@ -1348,9 +1352,9 @@ pub mod pybind {
#[new]
fn new(py_print_fn: PyObject) -> Self {
let py_print_fn1 = py_print_fn.clone();
let closure = move |s: String| {
let closure = move |s: &str| {
Python::with_gil(|py| -> PyResult<()> {
py_print_fn1.call1(py, (PyUnicode::new(py, &s),))?;
py_print_fn1.call1(py, (PyUnicode::new(py, s),))?;
Ok(())
})
.unwrap();
@ -1427,7 +1431,7 @@ pub mod pybind {
unwrap_me_mut!(self.wrapper, m, { m.set_start_time(time) });
}
fn display(&mut self, event_msg: String, sender_id: ClientId) {
fn display(&mut self, event_msg: &str, sender_id: ClientId) {
unwrap_me_mut!(self.wrapper, m, { m.display(event_msg, sender_id) });
}
}

View File

@ -1,7 +1,5 @@
//! Monitor to display both cumulative and per-client monitor
#[cfg(feature = "introspection")]
use alloc::string::ToString;
use alloc::{string::String, vec::Vec};
use core::{
fmt::{Debug, Formatter, Write},
@ -17,7 +15,7 @@ use crate::monitors::{ClientStats, Monitor};
#[derive(Clone)]
pub struct MultiMonitor<F>
where
F: FnMut(String),
F: FnMut(&str),
{
print_fn: F,
start_time: Duration,
@ -27,7 +25,7 @@ where
impl<F> Debug for MultiMonitor<F>
where
F: FnMut(String),
F: FnMut(&str),
{
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("MultiMonitor")
@ -39,7 +37,7 @@ where
impl<F> Monitor for MultiMonitor<F>
where
F: FnMut(String),
F: FnMut(&str),
{
/// the client monitor, mutable
fn client_stats_mut(&mut self) -> &mut Vec<ClientStats> {
@ -65,7 +63,7 @@ where
self.aggregator.aggregate(name, &self.client_stats);
}
fn display(&mut self, event_msg: String, sender_id: ClientId) {
fn display(&mut self, event_msg: &str, sender_id: ClientId) {
let sender = format!("#{}", sender_id.0);
let pad = if event_msg.len() + sender.len() < 13 {
" ".repeat(13 - event_msg.len() - sender.len())
@ -87,7 +85,7 @@ where
write!(global_fmt, ", {key}: {val}").unwrap();
}
(self.print_fn)(global_fmt);
(self.print_fn)(&global_fmt);
self.client_stats_insert(sender_id);
let client = self.client_stats_mut_for(sender_id);
@ -102,7 +100,7 @@ where
for (key, val) in &client.user_monitor {
write!(fmt, ", {key}: {val}").unwrap();
}
(self.print_fn)(fmt);
(self.print_fn)(&fmt);
// Only print perf monitor if the feature is enabled
#[cfg(feature = "introspection")]
@ -110,18 +108,18 @@ where
// Print the client performance monitor. Skip the Client 0 which is the broker
for (i, client) in self.client_stats.iter().skip(1).enumerate() {
let fmt = format!("Client {:03}:\n{}", i + 1, client.introspection_monitor);
(self.print_fn)(fmt);
(self.print_fn)(&fmt);
}
// Separate the spacing just a bit
(self.print_fn)("\n".to_string());
(self.print_fn)("\n");
}
}
}
impl<F> MultiMonitor<F>
where
F: FnMut(String),
F: FnMut(&str),
{
/// Creates the monitor, using the `current_time` as `start_time`.
pub fn new(print_fn: F) -> Self {

View File

@ -47,7 +47,7 @@ use crate::monitors::{ClientStats, Monitor, UserStatsValue};
#[derive(Clone)]
pub struct PrometheusMonitor<F>
where
F: FnMut(String),
F: FnMut(&str),
{
print_fn: F,
start_time: Duration,
@ -63,7 +63,7 @@ where
impl<F> Debug for PrometheusMonitor<F>
where
F: FnMut(String),
F: FnMut(&str),
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PrometheusMonitor")
@ -75,7 +75,7 @@ where
impl<F> Monitor for PrometheusMonitor<F>
where
F: FnMut(String),
F: FnMut(&str),
{
/// the client monitor, mutable
fn client_stats_mut(&mut self) -> &mut Vec<ClientStats> {
@ -98,7 +98,7 @@ where
}
#[allow(clippy::cast_sign_loss)]
fn display(&mut self, event_msg: String, sender_id: ClientId) {
fn display(&mut self, event_msg: &str, sender_id: ClientId) {
// Update the prometheus metrics
// Label each metric with the sender / client_id
// The gauges must take signed i64's, with max value of 2^63-1 so it is
@ -162,7 +162,7 @@ where
self.total_execs(),
self.execs_per_sec_pretty()
);
(self.print_fn)(fmt);
(self.print_fn)(&fmt);
self.client_stats_insert(sender_id);
let cur_client = self.client_stats_mut_for(sender_id);
@ -192,7 +192,7 @@ where
impl<F> PrometheusMonitor<F>
where
F: FnMut(String),
F: FnMut(&str),
{
pub fn new(listener: String, print_fn: F) -> Self {
// Gauge's implementation of clone uses Arc

View File

@ -357,7 +357,7 @@ impl Monitor for TuiMonitor {
}
#[allow(clippy::cast_sign_loss)]
fn display(&mut self, event_msg: String, sender_id: ClientId) {
fn display(&mut self, event_msg: &str, sender_id: ClientId) {
let cur_time = current_time();
{

View File

@ -1,9 +1,6 @@
//! Schedule the access to the Corpus.
use alloc::{
borrow::ToOwned,
string::{String, ToString},
};
use alloc::{borrow::ToOwned, string::ToString};
use core::marker::PhantomData;
pub mod testcase_score;
@ -155,7 +152,7 @@ where
fn set_last_hash(&mut self, value: usize);
/// Get the observer map observer name
fn map_observer_name(&self) -> &String;
fn map_observer_name(&self) -> &str;
/// Called when a [`Testcase`] is added to the corpus
fn on_add_metadata(&self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> {

View File

@ -230,7 +230,7 @@ where
self.last_hash = hash;
}
fn map_observer_name(&self) -> &String {
fn map_observer_name(&self) -> &str {
&self.map_observer_name
}
}

View File

@ -274,7 +274,7 @@ where
self.last_hash = hash;
}
fn map_observer_name(&self) -> &String {
fn map_observer_name(&self) -> &str {
&self.map_observer_name
}
}

View File

@ -175,7 +175,7 @@ where
})
}
fn create_monitor_closure() -> impl Fn(String) + Clone {
fn create_monitor_closure() -> impl Fn(&str) + Clone {
#[cfg(unix)]
let stderr_fd =
std::os::fd::RawFd::from_str(&std::env::var(crate::STDERR_FD_VAR).unwrap()).unwrap(); // set in main

View File

@ -394,7 +394,7 @@ where
fn find_function(
emu: &Emulator,
file: &String,
file: &str,
function: &str,
loadaddr: GuestAddr,
) -> Result<Option<GuestAddr>, Error> {