11//! The [`MultiMonitor`] displays both cumulative and per-client stats.
22
33use alloc:: string:: String ;
4- use core:: {
5- fmt:: { Debug , Formatter , Write } ,
6- time:: Duration ,
7- } ;
4+ use core:: fmt:: { Debug , Formatter , Write } ;
85
96use libafl_bolts:: { ClientId , Error , current_time} ;
107
1714 F : FnMut ( & str ) ,
1815{
1916 print_fn : F ,
17+ pizza_mode : bool ,
2018}
2119
2220impl < F > Debug for MultiMonitor < F >
@@ -46,16 +44,29 @@ where
4644 } ;
4745 let head = format ! ( "{event_msg}{pad} {sender}" ) ;
4846 let global_stats = client_stats_manager. global_stats ( ) ;
49- let mut global_fmt = format ! (
50- "[{}] (GLOBAL) run time: {}, clients: {}, corpus: {}, objectives: {}, executions: {}, exec/sec: {}" ,
51- head,
52- global_stats. run_time_pretty,
53- global_stats. client_stats_count,
54- global_stats. corpus_size,
55- global_stats. objective_size,
56- global_stats. total_execs,
57- global_stats. execs_per_sec_pretty
58- ) ;
47+ let mut global_fmt = if self . pizza_mode {
48+ format ! (
49+ "[{}] (GLOBAL) time to bake: {}, customers: {}, pizzas: {}, deliveries: {}, doughs: {}, p/s: {}, Pineapple pizzas: 0" ,
50+ head,
51+ global_stats. run_time_pretty,
52+ global_stats. client_stats_count,
53+ global_stats. corpus_size,
54+ global_stats. objective_size,
55+ global_stats. total_execs,
56+ global_stats. execs_per_sec_pretty
57+ )
58+ } else {
59+ format ! (
60+ "[{}] (GLOBAL) run time: {}, clients: {}, corpus: {}, objectives: {}, executions: {}, exec/sec: {}" ,
61+ head,
62+ global_stats. run_time_pretty,
63+ global_stats. client_stats_count,
64+ global_stats. corpus_size,
65+ global_stats. objective_size,
66+ global_stats. total_execs,
67+ global_stats. execs_per_sec_pretty
68+ )
69+ } ;
5970 for ( key, val) in client_stats_manager. aggregated ( ) {
6071 write ! ( global_fmt, ", {key}: {val}" ) . unwrap ( ) ;
6172 }
@@ -64,19 +75,29 @@ where
6475
6576 client_stats_manager. client_stats_insert ( sender_id) ?;
6677 let cur_time = current_time ( ) ;
67- let exec_sec = client_stats_manager
78+ let exec_sec_val = client_stats_manager
6879 . update_client_stats_for ( sender_id, |client| client. execs_per_sec_pretty ( cur_time) ) ?;
6980 let client = client_stats_manager. client_stats_for ( sender_id) ?;
7081
71- let pad = " " . repeat ( head. len ( ) ) ;
72- let mut fmt = format ! (
73- " {} (CLIENT) corpus: {}, objectives: {}, executions: {}, exec/sec: {}" ,
74- pad,
75- client. corpus_size( ) ,
76- client. objective_size( ) ,
77- client. executions( ) ,
78- exec_sec
79- ) ;
82+ let mut fmt = if self . pizza_mode {
83+ format ! (
84+ " {} (CUSTOMER) pizzas: {}, deliveries: {}, doughs: {}, p/s: {}" ,
85+ pad,
86+ client. corpus_size( ) ,
87+ client. objective_size( ) ,
88+ client. executions( ) ,
89+ exec_sec_val
90+ )
91+ } else {
92+ format ! (
93+ " {} (CLIENT) corpus: {}, objectives: {}, executions: {}, exec/sec: {}" ,
94+ pad,
95+ client. corpus_size( ) ,
96+ client. objective_size( ) ,
97+ client. executions( ) ,
98+ exec_sec_val
99+ )
100+ } ;
80101 for ( key, val) in client. user_stats ( ) {
81102 write ! ( fmt, ", {key}: {val}" ) . unwrap ( ) ;
82103 }
@@ -87,12 +108,29 @@ where
87108 {
88109 // Print the client performance monitor. Skip clients with no introspection data
89110 // (e.g., broker that never fuzzes will have elapsed_cycles == 0)
111+ let client_header = if self . pizza_mode {
112+ "Customer"
113+ } else {
114+ "Client"
115+ } ;
116+ let cycles_label = if self . pizza_mode {
117+ "pizzas baked"
118+ } else {
119+ "cycles"
120+ } ;
90121 for ( client_id, client) in client_stats_manager
91122 . client_stats ( )
92123 . iter ( )
93124 . filter ( |( _, x) | x. enabled ( ) && x. introspection_stats . elapsed_cycles ( ) > 0 )
94125 {
95- let fmt = format ! ( "Client {:03}:\n {}" , client_id. 0 , client. introspection_stats) ;
126+ let fmt = format ! (
127+ "{} {:03}:\n {} {}: {}" ,
128+ client_header,
129+ client_id. 0 ,
130+ client. introspection_stats,
131+ cycles_label,
132+ client. executions( )
133+ ) ;
96134 ( self . print_fn ) ( & fmt) ;
97135 }
98136
@@ -109,15 +147,14 @@ where
109147{
110148 /// Creates the monitor, using the `current_time` as `start_time`.
111149 pub fn new ( print_fn : F ) -> Self {
112- Self { print_fn }
150+ Self {
151+ print_fn,
152+ pizza_mode : crate :: monitors:: pizza_is_served ( ) ,
153+ }
113154 }
114155
115- /// Creates the monitor with a given `start_time`.
116- #[ deprecated(
117- since = "0.16.0" ,
118- note = "Please use new to create. start_time is useless here."
119- ) ]
120- pub fn with_time ( print_fn : F , _start_time : Duration ) -> Self {
121- Self :: new ( print_fn)
156+ /// Adds pineapple.
157+ pub fn add_pineapple ( & mut self ) {
158+ self . pizza_mode = false ;
122159 }
123160}
0 commit comments