Skip to content

Commit d317725

Browse files
WorksButNotTestedYour Name
andauthored
Add total execs to TUI (#3078)
* Add total execs to TUI * Pretty print large numbers --------- Co-authored-by: Your Name <you@example.com>
1 parent 8e32947 commit d317725

File tree

5 files changed

+66
-17
lines changed

5 files changed

+66
-17
lines changed

libafl/src/monitors/stats/manager.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,10 @@ impl ClientStatsManager {
170170

171171
/// Get process timing. `execs_per_sec_pretty` could be retrieved from `GlobalStats`.
172172
#[must_use]
173-
pub fn process_timing(&self, execs_per_sec_pretty: String) -> ProcessTiming {
173+
pub fn process_timing(&self, execs_per_sec_pretty: String, total_execs: u64) -> ProcessTiming {
174174
let mut total_process_timing = ProcessTiming::new();
175175
total_process_timing.exec_speed = execs_per_sec_pretty;
176+
total_process_timing.total_execs = total_execs;
176177
if self.client_stats().len() > 1 {
177178
let mut new_path_time = Duration::default();
178179
let mut new_objectives_time = Duration::default();

libafl/src/monitors/stats/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ pub struct ProcessTiming {
9494
pub last_new_entry: Duration,
9595
/// Timing of the last new solution
9696
pub last_saved_solution: Duration,
97+
/// The total number of executions
98+
pub total_execs: u64,
9799
}
98100

99101
impl ProcessTiming {
@@ -339,12 +341,14 @@ impl ClientStats {
339341
};
340342

341343
let exec_speed = self.execs_per_sec_pretty(current_time());
344+
let total_execs = self.executions;
342345

343346
ProcessTiming {
344347
client_start_time,
345348
exec_speed,
346349
last_new_entry,
347350
last_saved_solution,
351+
total_execs,
348352
}
349353
}
350354

libafl/src/monitors/tui/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crossterm::{
2626
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
2727
};
2828
use hashbrown::HashMap;
29-
use libafl_bolts::{ClientId, current_time, format_duration_hms};
29+
use libafl_bolts::{ClientId, current_time, format_big_number, format_duration_hms};
3030
use ratatui::{Terminal, backend::CrosstermBackend};
3131
use typed_builder::TypedBuilder;
3232

@@ -351,14 +351,16 @@ impl Monitor for TuiMonitor {
351351
let totalexec = global_stats.total_execs;
352352
let run_time = global_stats.run_time;
353353
let exec_per_sec_pretty = global_stats.execs_per_sec_pretty.clone();
354+
let total_execs = global_stats.total_execs;
354355
let mut ctx = self.context.write().unwrap();
355356
ctx.total_corpus_count = global_stats.corpus_size;
356357
ctx.total_solutions = global_stats.objective_size;
357358
ctx.corpus_size_timed
358359
.add(run_time, global_stats.corpus_size);
359360
ctx.objective_size_timed
360361
.add(run_time, global_stats.objective_size);
361-
let total_process_timing = client_stats_manager.process_timing(exec_per_sec_pretty);
362+
let total_process_timing =
363+
client_stats_manager.process_timing(exec_per_sec_pretty, total_execs);
362364

363365
ctx.total_process_timing = total_process_timing;
364366
ctx.execs_per_sec_timed.add(run_time, execsec);
@@ -391,9 +393,9 @@ impl Monitor for TuiMonitor {
391393
let mut fmt = format!(
392394
"[{}] corpus: {}, objectives: {}, executions: {}, exec/sec: {}",
393395
head,
394-
client.corpus_size(),
395-
client.objective_size(),
396-
client.executions(),
396+
format_big_number(client.corpus_size()),
397+
format_big_number(client.objective_size()),
398+
format_big_number(client.executions()),
397399
exec_sec
398400
);
399401
for (key, val) in client.user_stats() {

libafl/src/monitors/tui/ui.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use alloc::{string::ToString, sync::Arc, vec::Vec};
33
use core::cmp::{max, min};
44
use std::sync::RwLock;
55

6+
use libafl_bolts::format_big_number;
67
use ratatui::{
78
Frame,
89
layout::{Alignment, Constraint, Direction, Layout, Rect},
@@ -532,6 +533,10 @@ impl TuiUi {
532533
Cell::from(Span::raw("exec speed")),
533534
Cell::from(Span::raw(&tup.1.exec_speed)),
534535
]),
536+
Row::new(vec![
537+
Cell::from(Span::raw("total execs")),
538+
Cell::from(Span::raw(format_big_number(tup.1.total_execs))),
539+
]),
535540
Row::new(vec![
536541
Cell::from(Span::raw("last new entry")),
537542
Cell::from(Span::raw(format_duration_hms(&(tup.1.last_new_entry)))),
@@ -581,17 +586,17 @@ impl TuiUi {
581586
Cell::from(Span::raw("clients")),
582587
Cell::from(Span::raw(format!("{}", self.clients))),
583588
Cell::from(Span::raw("total execs")),
584-
Cell::from(Span::raw(format!("{}", app.total_execs))),
589+
Cell::from(Span::raw(format_big_number(app.total_execs))),
585590
Cell::from(Span::raw("map density")),
586591
Cell::from(Span::raw(app.total_map_density.to_string())),
587592
]),
588593
Row::new(vec![
589594
Cell::from(Span::raw("solutions")),
590-
Cell::from(Span::raw(format!("{}", app.total_solutions))),
595+
Cell::from(Span::raw(format_big_number(app.total_solutions))),
591596
Cell::from(Span::raw("cycle done")),
592-
Cell::from(Span::raw(format!("{}", app.total_cycles_done))),
597+
Cell::from(Span::raw(format_big_number(app.total_cycles_done))),
593598
Cell::from(Span::raw("corpus count")),
594-
Cell::from(Span::raw(format!("{}", app.total_corpus_count))),
599+
Cell::from(Span::raw(format_big_number(app.total_corpus_count))),
595600
]),
596601
]
597602
};
@@ -680,18 +685,16 @@ impl TuiUi {
680685
vec![
681686
Row::new(vec![
682687
Cell::from(Span::raw("corpus count")),
683-
Cell::from(Span::raw(format!(
684-
"{}",
685-
app.clients.get(&self.clients_idx).map_or(0, |x| x.corpus)
688+
Cell::from(Span::raw(format_big_number(
689+
app.clients.get(&self.clients_idx).map_or(0, |x| x.corpus),
686690
))),
687691
]),
688692
Row::new(vec![
689693
Cell::from(Span::raw("total execs")),
690-
Cell::from(Span::raw(format!(
691-
"{}",
694+
Cell::from(Span::raw(format_big_number(
692695
app.clients
693696
.get(&self.clients_idx)
694-
.map_or(0, |x| x.executions)
697+
.map_or(0, |x| x.executions),
695698
))),
696699
]),
697700
Row::new(vec![

libafl_bolts/src/lib.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ pub mod bolts_prelude {
140140
#[cfg(all(unix, feature = "std"))]
141141
use alloc::boxed::Box;
142142
#[cfg(feature = "alloc")]
143-
use alloc::{borrow::Cow, vec::Vec};
143+
use alloc::{borrow::Cow, string::ToString, vec::Vec};
144144
#[cfg(all(not(feature = "xxh3"), feature = "alloc"))]
145145
use core::hash::BuildHasher;
146146
#[cfg(any(feature = "xxh3", feature = "alloc"))]
@@ -945,6 +945,45 @@ pub fn format_duration_hms(duration: &time::Duration) -> String {
945945
format!("{}h-{}m-{}s", (secs / 60) / 60, (secs / 60) % 60, secs % 60)
946946
}
947947

948+
/// Format a number with thousands separators
949+
#[cfg(feature = "alloc")]
950+
#[must_use]
951+
pub fn format_big_number(val: u64) -> String {
952+
let short = {
953+
let (num, unit) = match val {
954+
0..=999 => return format!("{val}"),
955+
1_000..=999_999 => (1000, "K"),
956+
1_000_000..=999_999_999 => (1_000_000, "M"),
957+
1_000_000_000..=999_999_999_999 => (1_000_000_000, "G"),
958+
_ => (1_000_000_000_000, "T"),
959+
};
960+
let main = val / num;
961+
let frac = (val % num) / (num / 100);
962+
format!(
963+
"{}.{}{}",
964+
main,
965+
format!("{frac:02}").trim_end_matches('0'),
966+
unit
967+
)
968+
};
969+
let long = val
970+
.to_string()
971+
.chars()
972+
.rev()
973+
.enumerate()
974+
.fold(String::new(), |mut acc, (i, c)| {
975+
if i > 0 && i % 3 == 0 {
976+
acc.push(',');
977+
}
978+
acc.push(c);
979+
acc
980+
})
981+
.chars()
982+
.rev()
983+
.collect::<String>();
984+
format!("{short} ({long})")
985+
}
986+
948987
/// Stderr logger
949988
#[cfg(feature = "std")]
950989
pub static LIBAFL_STDERR_LOGGER: SimpleStderrLogger = SimpleStderrLogger::new();

0 commit comments

Comments
 (0)