Introduce TuiMonitor builder, clean up monitor docs and names (#2385)
* Introduce TuiMonitor builder * Some random docs * More documentation for monitors * fixed critical whitespace * Rename all-caps TOML and JSON to Toml and Json in monitors * actually rename * more
This commit is contained in:
parent
24aa640df7
commit
3c93b96b70
@ -6,6 +6,6 @@ Mutators can be composed, and they are generally linked to a specific Input type
|
|||||||
|
|
||||||
There can be, for instance, a Mutator that applies more than a single type of mutation to the input. Consider a generic Mutator for a byte stream, bit flip is just one of the possible mutations but not the only one, there is also, for instance, the random replacement of a byte of the copy of a chunk.
|
There can be, for instance, a Mutator that applies more than a single type of mutation to the input. Consider a generic Mutator for a byte stream, bit flip is just one of the possible mutations but not the only one, there is also, for instance, the random replacement of a byte of the copy of a chunk.
|
||||||
|
|
||||||
There are also mutators that always produce valid inputs, say a mutator that generates valid JSON or code, but these grammar based mutators need a grammar to work.
|
There are also mutators that always produce valid inputs, say a mutator that generates valid Json or code, but these grammar based mutators need a grammar to work.
|
||||||
|
|
||||||
In LibAFL, [`Mutator`](https://docs.rs/libafl/latest/libafl/mutators/trait.Mutator.html) is a trait.
|
In LibAFL, [`Mutator`](https://docs.rs/libafl/latest/libafl/mutators/trait.Mutator.html) is a trait.
|
||||||
|
@ -3,7 +3,7 @@ use std::ptr::write_volatile;
|
|||||||
use std::{path::PathBuf, ptr::write};
|
use std::{path::PathBuf, ptr::write};
|
||||||
|
|
||||||
#[cfg(feature = "tui")]
|
#[cfg(feature = "tui")]
|
||||||
use libafl::monitors::tui::{ui::TuiUI, TuiMonitor};
|
use libafl::monitors::tui::TuiMonitor;
|
||||||
#[cfg(not(feature = "tui"))]
|
#[cfg(not(feature = "tui"))]
|
||||||
use libafl::monitors::SimpleMonitor;
|
use libafl::monitors::SimpleMonitor;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
@ -118,9 +118,10 @@ pub fn main() {
|
|||||||
#[cfg(not(feature = "tui"))]
|
#[cfg(not(feature = "tui"))]
|
||||||
let mon = SimpleMonitor::new(|s| println!("{s}"));
|
let mon = SimpleMonitor::new(|s| println!("{s}"));
|
||||||
#[cfg(feature = "tui")]
|
#[cfg(feature = "tui")]
|
||||||
let ui = TuiUI::with_version(String::from("Baby Fuzzer"), String::from("0.0.1"), false);
|
let mon = TuiMonitor::builder()
|
||||||
#[cfg(feature = "tui")]
|
.title("Baby Fuzzer")
|
||||||
let mon = TuiMonitor::new(ui);
|
.enhanced_graphics(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
// The event manager handle the various events generated during the fuzzing loop
|
// The event manager handle the various events generated during the fuzzing loop
|
||||||
// such as the notification of the addition of a new item to the corpus
|
// such as the notification of the addition of a new item to the corpus
|
||||||
|
@ -6,7 +6,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "tui")]
|
#[cfg(feature = "tui")]
|
||||||
use libafl::monitors::tui::{ui::TuiUI, TuiMonitor};
|
use libafl::monitors::tui::TuiMonitor;
|
||||||
#[cfg(not(feature = "tui"))]
|
#[cfg(not(feature = "tui"))]
|
||||||
use libafl::monitors::SimpleMonitor;
|
use libafl::monitors::SimpleMonitor;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
@ -204,9 +204,10 @@ pub fn main() {
|
|||||||
#[cfg(not(feature = "tui"))]
|
#[cfg(not(feature = "tui"))]
|
||||||
let mon = SimpleMonitor::with_user_monitor(|s| println!("{s}"));
|
let mon = SimpleMonitor::with_user_monitor(|s| println!("{s}"));
|
||||||
#[cfg(feature = "tui")]
|
#[cfg(feature = "tui")]
|
||||||
let ui = TuiUI::new(String::from("Baby Fuzzer"), false);
|
let mon = TuiMonitor::builder()
|
||||||
#[cfg(feature = "tui")]
|
.title("Baby Fuzzer")
|
||||||
let mon = TuiMonitor::new(ui);
|
.enhanced_graphics(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
// The event manager handle the various events generated during the fuzzing loop
|
// The event manager handle the various events generated during the fuzzing loop
|
||||||
// such as the notification of the addition of a new item to the corpus
|
// such as the notification of the addition of a new item to the corpus
|
||||||
|
@ -3,7 +3,7 @@ use std::ptr::write_volatile;
|
|||||||
use std::{path::PathBuf, ptr::write};
|
use std::{path::PathBuf, ptr::write};
|
||||||
|
|
||||||
#[cfg(feature = "tui")]
|
#[cfg(feature = "tui")]
|
||||||
use libafl::monitors::tui::{ui::TuiUI, TuiMonitor};
|
use libafl::monitors::tui::TuiMonitor;
|
||||||
#[cfg(not(feature = "tui"))]
|
#[cfg(not(feature = "tui"))]
|
||||||
use libafl::monitors::SimpleMonitor;
|
use libafl::monitors::SimpleMonitor;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
@ -85,9 +85,11 @@ pub fn main() {
|
|||||||
#[cfg(not(feature = "tui"))]
|
#[cfg(not(feature = "tui"))]
|
||||||
let mon = SimpleMonitor::new(|s| println!("{s}"));
|
let mon = SimpleMonitor::new(|s| println!("{s}"));
|
||||||
#[cfg(feature = "tui")]
|
#[cfg(feature = "tui")]
|
||||||
let ui = TuiUI::with_version(String::from("Baby Fuzzer"), String::from("0.0.1"), false);
|
let mon = TuiMonitor::builder()
|
||||||
#[cfg(feature = "tui")]
|
.title("Baby Fuzzer")
|
||||||
let mon = TuiMonitor::new(ui);
|
.version("0.0.1")
|
||||||
|
.enhanced_graphics(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
// The event manager handle the various events generated during the fuzzing loop
|
// The event manager handle the various events generated during the fuzzing loop
|
||||||
// such as the notification of the addition of a new item to the corpus
|
// such as the notification of the addition of a new item to the corpus
|
||||||
|
@ -25,7 +25,7 @@ def concatenate_json_files(input_dir):
|
|||||||
with open(output_file, 'w') as file:
|
with open(output_file, 'w') as file:
|
||||||
json.dump([data], file)
|
json.dump([data], file)
|
||||||
|
|
||||||
print(f"JSON files concatenated successfully! Output file: {output_file}")
|
print(f"Json files concatenated successfully! Output file: {output_file}")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if len(sys.argv) != 2:
|
if len(sys.argv) != 2:
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
extern "C" __declspec(dllexport) size_t
|
extern "C" __declspec(dllexport) size_t
|
||||||
LLVMFuzzerTestOneInput(const char *data, unsigned int len) {
|
LLVMFuzzerTestOneInput(const char *data, unsigned int len) {
|
||||||
if (data[0] == 'b') {
|
if (data[0] == 'b') {
|
||||||
if (data[1] == 'a') {
|
if (data[1] == 'a') {
|
||||||
if (data[2] == 'd') {
|
if (data[2] == 'd') {
|
||||||
|
@ -13,7 +13,7 @@ use libafl::{
|
|||||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||||
fuzzer::{Fuzzer, StdFuzzer},
|
fuzzer::{Fuzzer, StdFuzzer},
|
||||||
inputs::{BytesInput, HasTargetBytes},
|
inputs::{BytesInput, HasTargetBytes},
|
||||||
monitors::tui::{ui::TuiUI, TuiMonitor},
|
monitors::tui::TuiMonitor,
|
||||||
mutators::{
|
mutators::{
|
||||||
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
|
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
|
||||||
token_mutations::Tokens,
|
token_mutations::Tokens,
|
||||||
@ -70,12 +70,12 @@ fn fuzz(
|
|||||||
// let monitor = MultiMonitor::new(|s| println!("{s}"));
|
// let monitor = MultiMonitor::new(|s| println!("{s}"));
|
||||||
|
|
||||||
//Setup an Monitor with AFL-Style UI to display the stats
|
//Setup an Monitor with AFL-Style UI to display the stats
|
||||||
let ui = TuiUI::with_version(
|
#[cfg(feature = "tui")]
|
||||||
String::from("Libfuzzer For Libpng"),
|
let monitor = TuiMonitor::builder()
|
||||||
String::from("0.0.1"),
|
.title("Libfuzzer in LibAFL")
|
||||||
false,
|
.version("0.0.1")
|
||||||
);
|
.enhanced_graphics(true)
|
||||||
let monitor = TuiMonitor::new(ui);
|
.build();
|
||||||
|
|
||||||
// The restarting state will spawn the same process again as child, then restarted it each time it crashes.
|
// The restarting state will spawn the same process again as child, then restarted it each time it crashes.
|
||||||
let (state, mut restarting_mgr) =
|
let (state, mut restarting_mgr) =
|
||||||
|
@ -14,7 +14,7 @@ use libafl::{
|
|||||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||||
fuzzer::{Fuzzer, StdFuzzer},
|
fuzzer::{Fuzzer, StdFuzzer},
|
||||||
inputs::{BytesInput, HasTargetBytes},
|
inputs::{BytesInput, HasTargetBytes},
|
||||||
monitors::{MultiMonitor, OnDiskTOMLMonitor},
|
monitors::{MultiMonitor, OnDiskTomlMonitor},
|
||||||
mutators::{
|
mutators::{
|
||||||
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
|
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
|
||||||
token_mutations::Tokens,
|
token_mutations::Tokens,
|
||||||
@ -131,7 +131,7 @@ pub extern "C" fn libafl_main() {
|
|||||||
|
|
||||||
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
|
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
|
||||||
|
|
||||||
let monitor = OnDiskTOMLMonitor::new(
|
let monitor = OnDiskTomlMonitor::new(
|
||||||
"./fuzzer_stats.toml",
|
"./fuzzer_stats.toml",
|
||||||
MultiMonitor::new(|s| println!("{s}")),
|
MultiMonitor::new(|s| println!("{s}")),
|
||||||
);
|
);
|
||||||
|
@ -18,7 +18,7 @@ use libafl::{
|
|||||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||||
fuzzer::{Fuzzer, StdFuzzer},
|
fuzzer::{Fuzzer, StdFuzzer},
|
||||||
inputs::{BytesInput, HasTargetBytes},
|
inputs::{BytesInput, HasTargetBytes},
|
||||||
monitors::{MultiMonitor, OnDiskTOMLMonitor},
|
monitors::{MultiMonitor, OnDiskTomlMonitor},
|
||||||
mutators::{
|
mutators::{
|
||||||
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
|
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
|
||||||
token_mutations::Tokens,
|
token_mutations::Tokens,
|
||||||
@ -154,7 +154,7 @@ pub extern "C" fn libafl_main() {
|
|||||||
|
|
||||||
let shmem_provider = MmapShMemProvider::new().expect("Failed to init shared memory");
|
let shmem_provider = MmapShMemProvider::new().expect("Failed to init shared memory");
|
||||||
|
|
||||||
let monitor = OnDiskTOMLMonitor::new(
|
let monitor = OnDiskTomlMonitor::new(
|
||||||
"./fuzzer_stats.toml",
|
"./fuzzer_stats.toml",
|
||||||
MultiMonitor::new(|s| println!("{s}")),
|
MultiMonitor::new(|s| println!("{s}")),
|
||||||
);
|
);
|
||||||
|
@ -5,7 +5,7 @@ use libafl::{
|
|||||||
events::SimpleEventManager,
|
events::SimpleEventManager,
|
||||||
feedbacks::{CrashFeedback, MaxMapFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback},
|
||||||
inputs::BytesInput,
|
inputs::BytesInput,
|
||||||
monitors::tui::{ui::TuiUI, TuiMonitor},
|
monitors::tui::TuiMonitor,
|
||||||
mutators::{havoc_mutations, StdScheduledMutator},
|
mutators::{havoc_mutations, StdScheduledMutator},
|
||||||
observers::StdMapObserver,
|
observers::StdMapObserver,
|
||||||
schedulers::RandScheduler,
|
schedulers::RandScheduler,
|
||||||
@ -40,8 +40,7 @@ fn main() {
|
|||||||
|
|
||||||
// switch monitor if you want
|
// switch monitor if you want
|
||||||
// let monitor = SimpleMonitor::new(|x|-> () {println!("{}",x)});
|
// let monitor = SimpleMonitor::new(|x|-> () {println!("{}",x)});
|
||||||
let ui = TuiUI::new(String::from("test_fuzz"), true);
|
let monitor = TuiMonitor::builder().title("test_fuzz").build();
|
||||||
let monitor = TuiMonitor::new(ui);
|
|
||||||
|
|
||||||
let mut mgr = SimpleEventManager::new(monitor);
|
let mut mgr = SimpleEventManager::new(monitor);
|
||||||
let mut executor = NyxExecutor::builder().build(helper, tuple_list!(observer));
|
let mut executor = NyxExecutor::builder().build(helper, tuple_list!(observer));
|
||||||
|
@ -10,10 +10,7 @@ use libafl::events::SimpleEventManager;
|
|||||||
#[cfg(not(feature = "simplemgr"))]
|
#[cfg(not(feature = "simplemgr"))]
|
||||||
use libafl::events::{EventConfig, Launcher, MonitorTypedEventManager};
|
use libafl::events::{EventConfig, Launcher, MonitorTypedEventManager};
|
||||||
use libafl::{
|
use libafl::{
|
||||||
monitors::{
|
monitors::{tui::TuiMonitor, Monitor, MultiMonitor},
|
||||||
tui::{ui::TuiUI, TuiMonitor},
|
|
||||||
Monitor, MultiMonitor,
|
|
||||||
},
|
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "simplemgr")]
|
#[cfg(feature = "simplemgr")]
|
||||||
@ -42,9 +39,11 @@ impl Fuzzer {
|
|||||||
|
|
||||||
pub fn fuzz(&self) -> Result<(), Error> {
|
pub fn fuzz(&self) -> Result<(), Error> {
|
||||||
if self.options.tui {
|
if self.options.tui {
|
||||||
let ui =
|
let monitor = TuiMonitor::builder()
|
||||||
TuiUI::with_version(String::from("QEMU Launcher"), String::from("0.10.1"), true);
|
.title("QEMU Launcher")
|
||||||
let monitor = TuiMonitor::new(ui);
|
.version("0.13.1")
|
||||||
|
.enhanced_graphics(true)
|
||||||
|
.build();
|
||||||
self.launch(monitor)
|
self.launch(monitor)
|
||||||
} else {
|
} else {
|
||||||
let log = self.options.log.as_ref().and_then(|l| {
|
let log = self.options.log.as_ref().and_then(|l| {
|
||||||
|
@ -24,9 +24,9 @@ use crate::{
|
|||||||
pub enum OnDiskMetadataFormat {
|
pub enum OnDiskMetadataFormat {
|
||||||
/// A binary-encoded postcard
|
/// A binary-encoded postcard
|
||||||
Postcard,
|
Postcard,
|
||||||
/// JSON
|
/// Json
|
||||||
Json,
|
Json,
|
||||||
/// JSON formatted for readability
|
/// Json formatted for readability
|
||||||
#[default]
|
#[default]
|
||||||
JsonPretty,
|
JsonPretty,
|
||||||
/// The same as [`OnDiskMetadataFormat::JsonPretty`], but compressed
|
/// The same as [`OnDiskMetadataFormat::JsonPretty`], but compressed
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//! Monitors that wrap a base one and log on disk
|
//! Monitors that wrap a base monitor and also log to disk using different formats.
|
||||||
|
|
||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{string::String, vec::Vec};
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
@ -13,9 +13,9 @@ use serde_json::json;
|
|||||||
|
|
||||||
use crate::monitors::{ClientStats, Monitor, NopMonitor};
|
use crate::monitors::{ClientStats, Monitor, NopMonitor};
|
||||||
|
|
||||||
/// Wrap a monitor and log the current state of the monitor into a TOML file.
|
/// Wrap a monitor and log the current state of the monitor into a Toml file.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct OnDiskTOMLMonitor<M>
|
pub struct OnDiskTomlMonitor<M>
|
||||||
where
|
where
|
||||||
M: Monitor,
|
M: Monitor,
|
||||||
{
|
{
|
||||||
@ -25,7 +25,7 @@ where
|
|||||||
update_interval: Duration,
|
update_interval: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M> Monitor for OnDiskTOMLMonitor<M>
|
impl<M> Monitor for OnDiskTomlMonitor<M>
|
||||||
where
|
where
|
||||||
M: Monitor,
|
M: Monitor,
|
||||||
{
|
{
|
||||||
@ -59,10 +59,10 @@ where
|
|||||||
if cur_time - self.last_update >= self.update_interval {
|
if cur_time - self.last_update >= self.update_interval {
|
||||||
self.last_update = cur_time;
|
self.last_update = cur_time;
|
||||||
|
|
||||||
let mut file = File::create(&self.filename).expect("Failed to open the TOML file");
|
let mut file = File::create(&self.filename).expect("Failed to open the Toml file");
|
||||||
write!(
|
write!(
|
||||||
&mut file,
|
&mut file,
|
||||||
"# This TOML is generated using the OnDiskMonitor component of LibAFL
|
"# This Toml is generated using the OnDiskMonitor component of LibAFL
|
||||||
|
|
||||||
[global]
|
[global]
|
||||||
run_time = \"{}\"
|
run_time = \"{}\"
|
||||||
@ -79,7 +79,7 @@ exec_sec = {}
|
|||||||
self.total_execs(),
|
self.total_execs(),
|
||||||
self.execs_per_sec()
|
self.execs_per_sec()
|
||||||
)
|
)
|
||||||
.expect("Failed to write to the TOML file");
|
.expect("Failed to write to the Toml file");
|
||||||
|
|
||||||
for (i, client) in self.client_stats_mut().iter_mut().enumerate() {
|
for (i, client) in self.client_stats_mut().iter_mut().enumerate() {
|
||||||
let exec_sec = client.execs_per_sec(cur_time);
|
let exec_sec = client.execs_per_sec(cur_time);
|
||||||
@ -95,7 +95,7 @@ exec_sec = {}
|
|||||||
",
|
",
|
||||||
i, client.corpus_size, client.objective_size, client.executions, exec_sec
|
i, client.corpus_size, client.objective_size, client.executions, exec_sec
|
||||||
)
|
)
|
||||||
.expect("Failed to write to the TOML file");
|
.expect("Failed to write to the Toml file");
|
||||||
|
|
||||||
for (key, val) in &client.user_monitor {
|
for (key, val) in &client.user_monitor {
|
||||||
let k: String = key
|
let k: String = key
|
||||||
@ -104,7 +104,7 @@ exec_sec = {}
|
|||||||
.filter(|c| c.is_alphanumeric() || *c == '_')
|
.filter(|c| c.is_alphanumeric() || *c == '_')
|
||||||
.collect();
|
.collect();
|
||||||
writeln!(&mut file, "{k} = \"{val}\"")
|
writeln!(&mut file, "{k} = \"{val}\"")
|
||||||
.expect("Failed to write to the TOML file");
|
.expect("Failed to write to the Toml file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,11 +115,11 @@ exec_sec = {}
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M> OnDiskTOMLMonitor<M>
|
impl<M> OnDiskTomlMonitor<M>
|
||||||
where
|
where
|
||||||
M: Monitor,
|
M: Monitor,
|
||||||
{
|
{
|
||||||
/// Create new [`OnDiskTOMLMonitor`]
|
/// Create new [`OnDiskTomlMonitor`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new<P>(filename: P, base: M) -> Self
|
pub fn new<P>(filename: P, base: M) -> Self
|
||||||
where
|
where
|
||||||
@ -128,7 +128,7 @@ where
|
|||||||
Self::with_update_interval(filename, base, Duration::from_secs(60))
|
Self::with_update_interval(filename, base, Duration::from_secs(60))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new [`OnDiskTOMLMonitor`] with custom update interval
|
/// Create new [`OnDiskTomlMonitor`] with custom update interval
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_update_interval<P>(filename: P, base: M, update_interval: Duration) -> Self
|
pub fn with_update_interval<P>(filename: P, base: M, update_interval: Duration) -> Self
|
||||||
where
|
where
|
||||||
@ -143,8 +143,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OnDiskTOMLMonitor<NopMonitor> {
|
impl OnDiskTomlMonitor<NopMonitor> {
|
||||||
/// Create new [`OnDiskTOMLMonitor`] without a base
|
/// Create new [`OnDiskTomlMonitor`] without a base
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn nop<P>(filename: P) -> Self
|
pub fn nop<P>(filename: P) -> Self
|
||||||
where
|
where
|
||||||
@ -155,8 +155,8 @@ impl OnDiskTOMLMonitor<NopMonitor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
/// Wraps a base monitor and continuously appends the current statistics to a JSON lines file.
|
/// Wraps a base monitor and continuously appends the current statistics to a Json lines file.
|
||||||
pub struct OnDiskJSONMonitor<F, M>
|
pub struct OnDiskJsonMonitor<F, M>
|
||||||
where
|
where
|
||||||
F: FnMut(&mut M) -> bool,
|
F: FnMut(&mut M) -> bool,
|
||||||
M: Monitor,
|
M: Monitor,
|
||||||
@ -167,12 +167,12 @@ where
|
|||||||
log_record: F,
|
log_record: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, M> OnDiskJSONMonitor<F, M>
|
impl<F, M> OnDiskJsonMonitor<F, M>
|
||||||
where
|
where
|
||||||
F: FnMut(&mut M) -> bool,
|
F: FnMut(&mut M) -> bool,
|
||||||
M: Monitor,
|
M: Monitor,
|
||||||
{
|
{
|
||||||
/// Create a new [`OnDiskJSONMonitor`]
|
/// Create a new [`OnDiskJsonMonitor`]
|
||||||
pub fn new<P>(filename: P, base: M, log_record: F) -> Self
|
pub fn new<P>(filename: P, base: M, log_record: F) -> Self
|
||||||
where
|
where
|
||||||
P: Into<PathBuf>,
|
P: Into<PathBuf>,
|
||||||
@ -187,7 +187,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, M> Monitor for OnDiskJSONMonitor<F, M>
|
impl<F, M> Monitor for OnDiskJsonMonitor<F, M>
|
||||||
where
|
where
|
||||||
F: FnMut(&mut M) -> bool,
|
F: FnMut(&mut M) -> bool,
|
||||||
M: Monitor,
|
M: Monitor,
|
||||||
@ -225,7 +225,7 @@ where
|
|||||||
"exec_sec": self.base.execs_per_sec(),
|
"exec_sec": self.base.execs_per_sec(),
|
||||||
"client_stats": self.client_stats(),
|
"client_stats": self.client_stats(),
|
||||||
});
|
});
|
||||||
writeln!(&file, "{line}").expect("Unable to write JSON to file");
|
writeln!(&file, "{line}").expect("Unable to write Json to file");
|
||||||
}
|
}
|
||||||
self.base.display(event_msg, sender_id);
|
self.base.display(event_msg, sender_id);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ pub mod multi;
|
|||||||
pub use multi::MultiMonitor;
|
pub use multi::MultiMonitor;
|
||||||
|
|
||||||
#[cfg(all(feature = "tui_monitor", feature = "std"))]
|
#[cfg(all(feature = "tui_monitor", feature = "std"))]
|
||||||
#[allow(missing_docs)]
|
|
||||||
pub mod tui;
|
pub mod tui;
|
||||||
|
|
||||||
#[cfg(all(feature = "prometheus_monitor", feature = "std"))]
|
#[cfg(all(feature = "prometheus_monitor", feature = "std"))]
|
||||||
@ -20,7 +19,7 @@ use alloc::{borrow::Cow, fmt::Debug, string::String, vec::Vec};
|
|||||||
use core::{fmt, fmt::Write, time::Duration};
|
use core::{fmt, fmt::Write, time::Duration};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use disk::{OnDiskJSONMonitor, OnDiskTOMLMonitor};
|
pub use disk::{OnDiskJsonMonitor, OnDiskTomlMonitor};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libafl_bolts::{current_time, format_duration_hms, ClientId};
|
use libafl_bolts::{current_time, format_duration_hms, ClientId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -1,26 +1,31 @@
|
|||||||
// ===== overview for prommon =====
|
//! Prometheus Monitor to log to a prometheus endpoint.
|
||||||
// The client (i.e., the fuzzer) sets up an HTTP endpoint (/metrics).
|
//!
|
||||||
// The endpoint contains metrics such as execution rate.
|
//! ## Overview
|
||||||
|
//!
|
||||||
// A prometheus server (can use a precompiled binary or docker) then scrapes \
|
//! The client (i.e., the fuzzer) sets up an HTTP endpoint (/metrics).
|
||||||
// the endpoint at regular intervals (configurable via prometheus.yml file).
|
//! The endpoint contains metrics such as execution rate.
|
||||||
// ====================
|
//!
|
||||||
//
|
//! A prometheus server (can use a precompiled binary or docker) then scrapes \
|
||||||
// == how to use it ===
|
//! the endpoint at regular intervals (configurable via prometheus.yml file).
|
||||||
// This monitor should plug into any fuzzer similar to other monitors.
|
//!
|
||||||
// In your fuzzer, include:
|
//! ## How to use it
|
||||||
// ```rust,ignore
|
//!
|
||||||
// use libafl::monitors::PrometheusMonitor;
|
//! This monitor should plug into any fuzzer similar to other monitors.
|
||||||
// ```
|
//! In your fuzzer:
|
||||||
// as well as:
|
//!
|
||||||
// ```rust,ignore
|
//! ```rust
|
||||||
// let listener = "127.0.0.1:8080".to_string(); // point prometheus to scrape here in your prometheus.yml
|
//! // First, include:
|
||||||
// let mon = PrometheusMonitor::new(listener, |s| log::info!("{s}"));
|
//! use libafl::monitors::PrometheusMonitor;
|
||||||
// and then like with any other monitor, pass it into the event manager like so:
|
//!
|
||||||
// let mut mgr = SimpleEventManager::new(mon);
|
//! // Then, create the monitor:
|
||||||
// ```
|
//! let listener = "127.0.0.1:8080".to_string(); // point prometheus to scrape here in your prometheus.yml
|
||||||
// When using docker, you may need to point prometheus.yml to the docker0 interface or host.docker.internal
|
//! let mon = PrometheusMonitor::new(listener, |s| log::info!("{s}"));
|
||||||
// ====================
|
//!
|
||||||
|
//! // and finally, like with any other monitor, pass it into the event manager like so:
|
||||||
|
//! // let mgr = SimpleEventManager::new(mon);
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! When using docker, you may need to point `prometheus.yml` to the `docker0` interface or `host.docker.internal`
|
||||||
|
|
||||||
use alloc::{borrow::Cow, fmt::Debug, string::String, vec::Vec};
|
use alloc::{borrow::Cow, fmt::Debug, string::String, vec::Vec};
|
||||||
use core::{fmt, time::Duration};
|
use core::{fmt, time::Duration};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//! Monitor based on ratatui
|
//! Fancy-looking terminal UI monitor, similar to AFL, based on [ratatui](https://ratatui.rs/)
|
||||||
|
|
||||||
use alloc::{borrow::Cow, boxed::Box, string::ToString};
|
use alloc::{borrow::Cow, boxed::Box, string::ToString};
|
||||||
use core::cmp;
|
use core::cmp;
|
||||||
@ -24,30 +24,60 @@ use hashbrown::HashMap;
|
|||||||
use libafl_bolts::{current_time, format_duration_hms, ClientId};
|
use libafl_bolts::{current_time, format_duration_hms, ClientId};
|
||||||
use ratatui::{backend::CrosstermBackend, Terminal};
|
use ratatui::{backend::CrosstermBackend, Terminal};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
use typed_builder::TypedBuilder;
|
||||||
|
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
use super::{ClientPerfMonitor, PerfFeature};
|
use super::{ClientPerfMonitor, PerfFeature};
|
||||||
use crate::monitors::{Aggregator, AggregatorOps, ClientStats, Monitor, UserStats, UserStatsValue};
|
use crate::monitors::{Aggregator, AggregatorOps, ClientStats, Monitor, UserStats, UserStatsValue};
|
||||||
|
|
||||||
|
#[allow(missing_docs)]
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
use ui::TuiUI;
|
use ui::TuiUi;
|
||||||
|
|
||||||
const DEFAULT_TIME_WINDOW: u64 = 60 * 10; // 10 min
|
const DEFAULT_TIME_WINDOW: u64 = 60 * 10; // 10 min
|
||||||
const DEFAULT_LOGS_NUMBER: usize = 128;
|
const DEFAULT_LOGS_NUMBER: usize = 128;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, TypedBuilder)]
|
||||||
|
#[builder(build_method(into = TuiMonitor), builder_method(vis = "pub(crate)",
|
||||||
|
doc = "Build the [`TuiMonitor`] from the set values"))]
|
||||||
|
/// Settings to create a new [`TuiMonitor`].
|
||||||
|
/// Use `TuiMonitor::builder()` or create this config and call `.into()` to create a new [`TuiMonitor`].
|
||||||
|
pub struct TuiMonitorConfig {
|
||||||
|
/// The title to show
|
||||||
|
#[builder(default_code = r#""LibAFL Fuzzer".to_string()"#, setter(into))]
|
||||||
|
pub title: String,
|
||||||
|
/// A version string to show for this (optional)
|
||||||
|
#[builder(default_code = r#""default".to_string()"#, setter(into))]
|
||||||
|
pub version: String,
|
||||||
|
/// Creates the monitor with an explicit `start_time`.
|
||||||
|
/// If nothings was set, this will use [`current_time`] instead.
|
||||||
|
#[builder(default_code = "current_time()")]
|
||||||
|
pub start_time: Duration,
|
||||||
|
/// Enables unicode TUI graphics, Looks better but may interfere with old terminals.
|
||||||
|
#[builder(default = true)]
|
||||||
|
pub enhanced_graphics: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A single status entry for timings
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct TimedStat {
|
pub struct TimedStat {
|
||||||
|
/// The time
|
||||||
pub time: Duration,
|
pub time: Duration,
|
||||||
|
/// The item
|
||||||
pub item: u64,
|
pub item: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Stats for timings
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TimedStats {
|
pub struct TimedStats {
|
||||||
|
/// Series of [`TimedStat`] entries
|
||||||
pub series: VecDeque<TimedStat>,
|
pub series: VecDeque<TimedStat>,
|
||||||
|
/// The time window to keep track of
|
||||||
pub window: Duration,
|
pub window: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TimedStats {
|
impl TimedStats {
|
||||||
|
/// Create a new [`TimedStats`] struct
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(window: Duration) -> Self {
|
pub fn new(window: Duration) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -56,6 +86,7 @@ impl TimedStats {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a stat datapoint
|
||||||
pub fn add(&mut self, time: Duration, item: u64) {
|
pub fn add(&mut self, time: Duration, item: u64) {
|
||||||
if self.series.is_empty() || self.series.back().unwrap().item != item {
|
if self.series.is_empty() || self.series.back().unwrap().item != item {
|
||||||
if self.series.front().is_some()
|
if self.series.front().is_some()
|
||||||
@ -67,6 +98,7 @@ impl TimedStats {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a stat datapoint for the `current_time`
|
||||||
pub fn add_now(&mut self, item: u64) {
|
pub fn add_now(&mut self, item: u64) {
|
||||||
if self.series.is_empty() || self.series[self.series.len() - 1].item != item {
|
if self.series.is_empty() || self.series[self.series.len() - 1].item != item {
|
||||||
let time = current_time();
|
let time = current_time();
|
||||||
@ -79,6 +111,7 @@ impl TimedStats {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change the window duration
|
||||||
pub fn update_window(&mut self, window: Duration) {
|
pub fn update_window(&mut self, window: Duration) {
|
||||||
self.window = window;
|
self.window = window;
|
||||||
while !self.series.is_empty()
|
while !self.series.is_empty()
|
||||||
@ -89,6 +122,7 @@ impl TimedStats {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The context to show performance metrics
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct PerfTuiContext {
|
pub struct PerfTuiContext {
|
||||||
@ -101,6 +135,7 @@ pub struct PerfTuiContext {
|
|||||||
|
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
impl PerfTuiContext {
|
impl PerfTuiContext {
|
||||||
|
/// Get the data for performance metrics
|
||||||
#[allow(clippy::cast_precision_loss)]
|
#[allow(clippy::cast_precision_loss)]
|
||||||
pub fn grab_data(&mut self, m: &ClientPerfMonitor) {
|
pub fn grab_data(&mut self, m: &ClientPerfMonitor) {
|
||||||
// Calculate the elapsed time from the monitor
|
// Calculate the elapsed time from the monitor
|
||||||
@ -164,15 +199,21 @@ impl PerfTuiContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Data struct to process timings
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct ProcessTiming {
|
pub struct ProcessTiming {
|
||||||
|
/// The start time
|
||||||
pub client_start_time: Duration,
|
pub client_start_time: Duration,
|
||||||
|
/// The executions speed
|
||||||
pub exec_speed: String,
|
pub exec_speed: String,
|
||||||
|
/// Timing of the last new corpus entry
|
||||||
pub last_new_entry: Duration,
|
pub last_new_entry: Duration,
|
||||||
|
/// Timing of the last new solution
|
||||||
pub last_saved_solution: Duration,
|
pub last_saved_solution: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProcessTiming {
|
impl ProcessTiming {
|
||||||
|
/// Create a new [`ProcessTiming`] struct
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
exec_speed: "0".to_string(),
|
exec_speed: "0".to_string(),
|
||||||
@ -181,6 +222,8 @@ impl ProcessTiming {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The geometry of a single data point
|
||||||
|
#[allow(missing_docs)]
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct ItemGeometry {
|
pub struct ItemGeometry {
|
||||||
pub pending: u64,
|
pub pending: u64,
|
||||||
@ -199,6 +242,8 @@ impl ItemGeometry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The context for a single client tracked in this [`TuiMonitor`]
|
||||||
|
#[allow(missing_docs)]
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct ClientTuiContext {
|
pub struct ClientTuiContext {
|
||||||
pub corpus: u64,
|
pub corpus: u64,
|
||||||
@ -215,6 +260,7 @@ pub struct ClientTuiContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ClientTuiContext {
|
impl ClientTuiContext {
|
||||||
|
/// Grab data for a single client
|
||||||
pub fn grab_data(&mut self, client: &ClientStats, exec_sec: String) {
|
pub fn grab_data(&mut self, client: &ClientStats, exec_sec: String) {
|
||||||
self.corpus = client.corpus_size;
|
self.corpus = client.corpus_size;
|
||||||
self.objectives = client.objective_size;
|
self.objectives = client.objective_size;
|
||||||
@ -267,6 +313,8 @@ impl ClientTuiContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The [`TuiContext`] for this [`TuiMonitor`]
|
||||||
|
#[allow(missing_docs)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TuiContext {
|
pub struct TuiContext {
|
||||||
pub graphs: Vec<String>,
|
pub graphs: Vec<String>,
|
||||||
@ -326,7 +374,7 @@ impl TuiContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tracking monitor during fuzzing and display with ratatui
|
/// Tracking monitor during fuzzing and display with [`ratatui`](https://ratatui.rs/)
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TuiMonitor {
|
pub struct TuiMonitor {
|
||||||
pub(crate) context: Arc<RwLock<TuiContext>>,
|
pub(crate) context: Arc<RwLock<TuiContext>>,
|
||||||
@ -336,6 +384,16 @@ pub struct TuiMonitor {
|
|||||||
aggregator: Aggregator,
|
aggregator: Aggregator,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<TuiMonitorConfig> for TuiMonitor {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
fn from(builder: TuiMonitorConfig) -> Self {
|
||||||
|
Self::with_time(
|
||||||
|
TuiUi::with_version(builder.title, builder.version, builder.enhanced_graphics),
|
||||||
|
builder.start_time,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Monitor for TuiMonitor {
|
impl Monitor for TuiMonitor {
|
||||||
/// The client monitor, mutable
|
/// The client monitor, mutable
|
||||||
/// This also includes disabled "padding" clients.
|
/// This also includes disabled "padding" clients.
|
||||||
@ -443,15 +501,35 @@ impl Monitor for TuiMonitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TuiMonitor {
|
impl TuiMonitor {
|
||||||
/// Creates the monitor
|
/// Create a builder for [`TuiMonitor`]
|
||||||
|
pub fn builder() -> TuiMonitorConfigBuilder {
|
||||||
|
TuiMonitorConfig::builder()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates the monitor.
|
||||||
|
///
|
||||||
|
/// # Deprecation Note
|
||||||
|
/// Use `TuiMonitor::builder()` instead.
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.13.2",
|
||||||
|
note = "Please use TuiMonitor::builder() instead of creating TuiUi directly."
|
||||||
|
)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(tui_ui: TuiUI) -> Self {
|
#[allow(deprecated)]
|
||||||
|
pub fn new(tui_ui: TuiUi) -> Self {
|
||||||
Self::with_time(tui_ui, current_time())
|
Self::with_time(tui_ui, current_time())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates the monitor with a given `start_time`.
|
/// Creates the monitor with a given `start_time`.
|
||||||
|
///
|
||||||
|
/// # Deprecation Note
|
||||||
|
/// Use `TuiMonitor::builder()` instead.
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.13.2",
|
||||||
|
note = "Please use TuiMonitor::builder() instead of creating TuiUi directly."
|
||||||
|
)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_time(tui_ui: TuiUI, start_time: Duration) -> Self {
|
pub fn with_time(tui_ui: TuiUi, start_time: Duration) -> Self {
|
||||||
let context = Arc::new(RwLock::new(TuiContext::new(start_time)));
|
let context = Arc::new(RwLock::new(TuiContext::new(start_time)));
|
||||||
|
|
||||||
enable_raw_mode().unwrap();
|
enable_raw_mode().unwrap();
|
||||||
@ -565,7 +643,7 @@ impl TuiMonitor {
|
|||||||
fn run_tui_thread<W: Write + Send + Sync + 'static>(
|
fn run_tui_thread<W: Write + Send + Sync + 'static>(
|
||||||
context: Arc<RwLock<TuiContext>>,
|
context: Arc<RwLock<TuiContext>>,
|
||||||
tick_rate: Duration,
|
tick_rate: Duration,
|
||||||
tui_ui: TuiUI,
|
tui_ui: TuiUi,
|
||||||
stdout_provider: impl Send + Sync + 'static + Fn() -> W,
|
stdout_provider: impl Send + Sync + 'static + Fn() -> W,
|
||||||
) {
|
) {
|
||||||
thread::spawn(move || -> io::Result<()> {
|
thread::spawn(move || -> io::Result<()> {
|
||||||
|
@ -21,7 +21,7 @@ use super::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct TuiUI {
|
pub struct TuiUi {
|
||||||
title: String,
|
title: String,
|
||||||
version: String,
|
version: String,
|
||||||
enhanced_graphics: bool,
|
enhanced_graphics: bool,
|
||||||
@ -34,13 +34,13 @@ pub struct TuiUI {
|
|||||||
pub should_quit: bool,
|
pub should_quit: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TuiUI {
|
impl TuiUi {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(title: String, enhanced_graphics: bool) -> Self {
|
pub fn new(title: String, enhanced_graphics: bool) -> Self {
|
||||||
Self::with_version(title, String::from("default"), enhanced_graphics)
|
Self::with_version(title, String::from("default"), enhanced_graphics)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the TuiUI with a given `version`.
|
// create the TuiUi with a given `version`.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_version(title: String, version: String, enhanced_graphics: bool) -> Self {
|
pub fn with_version(title: String, version: String, enhanced_graphics: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -49,7 +49,7 @@ impl TuiUI {
|
|||||||
enhanced_graphics,
|
enhanced_graphics,
|
||||||
show_logs: true,
|
show_logs: true,
|
||||||
clients_idx: 1,
|
clients_idx: 1,
|
||||||
..TuiUI::default()
|
..TuiUi::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn on_key(&mut self, c: char) {
|
pub fn on_key(&mut self, c: char) {
|
||||||
|
@ -18,10 +18,7 @@ use libafl::{
|
|||||||
},
|
},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
monitors::{
|
monitors::{tui::TuiMonitor, Monitor, MultiMonitor},
|
||||||
tui::{ui::TuiUI, TuiMonitor},
|
|
||||||
Monitor, MultiMonitor,
|
|
||||||
},
|
|
||||||
stages::{HasCurrentStage, StagesTuple},
|
stages::{HasCurrentStage, StagesTuple},
|
||||||
state::{HasExecutions, HasLastReportTime, HasSolutions, Stoppable, UsesState},
|
state::{HasExecutions, HasLastReportTime, HasSolutions, Stoppable, UsesState},
|
||||||
Error, Fuzzer, HasMetadata,
|
Error, Fuzzer, HasMetadata,
|
||||||
@ -208,7 +205,10 @@ pub fn fuzz(
|
|||||||
if let Some(forks) = options.forks() {
|
if let Some(forks) = options.forks() {
|
||||||
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
|
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
|
||||||
if options.tui() {
|
if options.tui() {
|
||||||
let monitor = TuiMonitor::new(TuiUI::new(options.fuzzer_name().to_string(), true));
|
let monitor = TuiMonitor::builder()
|
||||||
|
.title(options.fuzzer_name())
|
||||||
|
.enhanced_graphics(true)
|
||||||
|
.build();
|
||||||
fuzz_many_forking(options, harness, shmem_provider, forks, monitor)
|
fuzz_many_forking(options, harness, shmem_provider, forks, monitor)
|
||||||
} else if forks == 1 {
|
} else if forks == 1 {
|
||||||
let monitor = MultiMonitor::with_time(
|
let monitor = MultiMonitor::with_time(
|
||||||
@ -227,7 +227,10 @@ pub fn fuzz(
|
|||||||
// if the user specifies TUI, we assume they want to fork; it would not be possible to use
|
// if the user specifies TUI, we assume they want to fork; it would not be possible to use
|
||||||
// TUI safely otherwise
|
// TUI safely otherwise
|
||||||
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
|
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
|
||||||
let monitor = TuiMonitor::new(TuiUI::new(options.fuzzer_name().to_string(), true));
|
let monitor = TuiMonitor::builder()
|
||||||
|
.title(options.fuzzer_name())
|
||||||
|
.enhanced_graphics(true)
|
||||||
|
.build();
|
||||||
fuzz_many_forking(options, harness, shmem_provider, 1, monitor)
|
fuzz_many_forking(options, harness, shmem_provider, 1, monitor)
|
||||||
} else {
|
} else {
|
||||||
destroy_output_fds(options);
|
destroy_output_fds(options);
|
||||||
|
@ -35,6 +35,8 @@ for task in output[
|
|||||||
print(os.environ)
|
print(os.environ)
|
||||||
if "libafl_frida" in task:
|
if "libafl_frida" in task:
|
||||||
# DOCS_RS is needed for libafl_frida to build without auto-download feature
|
# DOCS_RS is needed for libafl_frida to build without auto-download feature
|
||||||
cargo_check = subprocess.check_output(task, shell=True, text=True, env=dict(os.environ, DOCS_RS="1"))
|
cargo_check = subprocess.check_output(
|
||||||
|
task, shell=True, text=True, env=dict(os.environ, DOCS_RS="1")
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
cargo_check = subprocess.check_output(task, shell=True, text=True)
|
cargo_check = subprocess.check_output(task, shell=True, text=True)
|
Loading…
x
Reference in New Issue
Block a user