Skip to content

Commit 7ea4070

Browse files
authored
Fix TUI (#3151)
1 parent 6372148 commit 7ea4070

File tree

3 files changed

+42
-34
lines changed

3 files changed

+42
-34
lines changed

libafl/src/monitors/stats/manager.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ impl ClientStatsManager {
230230
#[must_use]
231231
pub fn item_geometry(&self) -> ItemGeometry {
232232
let mut total_item_geometry = ItemGeometry::new();
233-
if self.client_stats().len() < 2 {
233+
if self.client_stats.is_empty() {
234234
return total_item_geometry;
235235
}
236236
let mut ratio_a: u64 = 0;
@@ -240,23 +240,15 @@ impl ClientStatsManager {
240240
.iter()
241241
.filter(|(_, client)| client.enabled())
242242
{
243-
let afl_stats = client
244-
.get_user_stats("AflStats")
245-
.map_or("None".to_string(), ToString::to_string);
243+
let afl_stats = client.get_user_stats("AflStats");
246244
let stability = client.get_user_stats("stability").map_or(
247245
UserStats::new(UserStatsValue::Ratio(0, 100), AggregatorOps::Avg),
248246
Clone::clone,
249247
);
250248

251-
if afl_stats != "None" {
252-
let default_json = serde_json::json!({
253-
"pending": 0,
254-
"pend_fav": 0,
255-
"imported": 0,
256-
"own_finds": 0,
257-
});
258-
let afl_stats_json: Value =
259-
serde_json::from_str(afl_stats.as_str()).unwrap_or(default_json);
249+
if let Some(stat) = afl_stats {
250+
let stats = stat.to_string();
251+
let afl_stats_json: Value = serde_json::from_str(stats.as_str()).unwrap();
260252
total_item_geometry.pending +=
261253
afl_stats_json["pending"].as_u64().unwrap_or_default();
262254
total_item_geometry.pend_fav +=
@@ -277,6 +269,7 @@ impl ClientStatsManager {
277269
} else {
278270
Some((ratio_a as f64) / (ratio_b as f64))
279271
};
272+
280273
total_item_geometry
281274
}
282275
}

libafl/src/monitors/tui/ui.rs

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! The UI-specific parts of [`super::TuiMonitor`]
2-
use alloc::{string::ToString, sync::Arc, vec::Vec};
2+
use alloc::{sync::Arc, vec::Vec};
33
use core::cmp::{max, min};
44
use std::sync::RwLock;
55

@@ -27,13 +27,27 @@ pub struct TuiUi {
2727
enhanced_graphics: bool,
2828
show_logs: bool,
2929
client_idx: usize,
30-
clients: usize,
30+
clients: Vec<usize>,
3131
charts_tab_idx: usize,
3232
graph_data: Vec<(f64, f64)>,
3333

3434
pub should_quit: bool,
3535
}
3636

37+
fn next_larger(sorted: &[usize], value: usize) -> Option<usize> {
38+
if let Some(index) = sorted.iter().position(|x| *x > value) {
39+
return Some(index);
40+
}
41+
None
42+
}
43+
44+
fn next_smaller(sorted: &[usize], value: usize) -> Option<usize> {
45+
if let Some(index) = sorted.iter().rposition(|x| *x < value) {
46+
return Some(index);
47+
}
48+
None
49+
}
50+
3751
impl TuiUi {
3852
#[must_use]
3953
pub fn new(title: String, enhanced_graphics: bool) -> Self {
@@ -68,20 +82,31 @@ impl TuiUi {
6882
}
6983

7084
pub fn on_right(&mut self) {
71-
if self.clients > 0 && self.client_idx < self.clients - 1 {
72-
self.client_idx += 1;
85+
if let Some(idx) = next_larger(&self.clients, self.client_idx) {
86+
self.client_idx = self.clients[idx];
7387
}
7488
}
7589

7690
pub fn on_left(&mut self) {
77-
if self.client_idx > 0 {
78-
self.client_idx -= 1;
91+
if let Some(idx) = next_smaller(&self.clients, self.client_idx) {
92+
self.client_idx = self.clients[idx];
7993
}
8094
}
8195

8296
/// Draw the current TUI context
8397
pub fn draw(&mut self, f: &mut Frame, app: &Arc<RwLock<TuiContext>>) {
84-
self.clients = app.read().unwrap().clients_num;
98+
let new = app.read().unwrap().clients_num;
99+
if new != self.clients.len() {
100+
// get the list of all clients
101+
let mut all: Vec<usize> = app.read().unwrap().clients.keys().copied().collect();
102+
all.sort_unstable();
103+
104+
// move the current client to the first one
105+
self.client_idx = all[0];
106+
107+
// move the vector holding all clients ids
108+
self.clients = all;
109+
}
85110

86111
let body = Layout::default()
87112
.constraints(if self.show_logs {
@@ -417,7 +442,7 @@ impl TuiUi {
417442
let empty_geometry: ItemGeometry = ItemGeometry::new();
418443
let item_geometry: &ItemGeometry = if is_overall {
419444
&tui_context.total_item_geometry
420-
} else if self.clients == 0 {
445+
} else if self.clients.is_empty() {
421446
&empty_geometry
422447
} else {
423448
let clients = &tui_context.clients;
@@ -494,7 +519,7 @@ impl TuiUi {
494519
let empty_timing: ProcessTiming = ProcessTiming::new();
495520
let tup: (Duration, &ProcessTiming) = if is_overall {
496521
(tui_context.start_time, &tui_context.total_process_timing)
497-
} else if self.clients == 0 {
522+
} else if self.clients.is_empty() {
498523
(current_time(), &empty_timing)
499524
} else {
500525
let clients = &tui_context.clients;
@@ -570,11 +595,9 @@ impl TuiUi {
570595
vec![
571596
Row::new(vec![
572597
Cell::from(Span::raw("clients")),
573-
Cell::from(Span::raw(format!("{}", self.clients))),
598+
Cell::from(Span::raw(format!("{}", self.clients.len()))),
574599
Cell::from(Span::raw("total execs")),
575600
Cell::from(Span::raw(format_big_number(app.total_execs))),
576-
Cell::from(Span::raw("map density")),
577-
Cell::from(Span::raw(app.total_map_density.to_string())),
578601
]),
579602
Row::new(vec![
580603
Cell::from(Span::raw("solutions")),
@@ -683,14 +706,6 @@ impl TuiUi {
683706
.map_or(0, |x| x.executions),
684707
))),
685708
]),
686-
Row::new(vec![
687-
Cell::from(Span::raw("map density")),
688-
Cell::from(Span::raw(
689-
app.clients
690-
.get(&self.client_idx)
691-
.map_or("0%".to_string(), |x| x.map_density.to_string()),
692-
)),
693-
]),
694709
]
695710
};
696711

libafl/src/stages/afl_stats.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ where
410410
"{{\
411411
\"pending\":{},\
412412
\"pending_fav\":{},\
413-
\"own_finds:\"{},\
413+
\"own_finds\":{},\
414414
\"imported\":{}\
415415
}}",
416416
stats.pending_total, stats.pending_favs, stats.corpus_found, stats.corpus_imported

0 commit comments

Comments
 (0)