1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
pub mod map;
pub use map::*;
pub mod cmp;
pub use cmp::*;
use alloc::string::{String, ToString};
use core::time::Duration;
use serde::{Deserialize, Serialize};
use crate::{
bolts::{
current_time,
tuples::{MatchName, Named},
},
executors::HasExecHooks,
Error,
};
pub trait Observer: Named + serde::Serialize + serde::de::DeserializeOwned {
#[inline]
fn flush(&mut self) -> Result<(), Error> {
Ok(())
}
}
pub trait ObserversTuple: MatchName + serde::Serialize + serde::de::DeserializeOwned {}
impl ObserversTuple for () {}
impl<Head, Tail> ObserversTuple for (Head, Tail)
where
Head: Observer,
Tail: ObserversTuple,
{
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TimeObserver {
name: String,
start_time: Duration,
last_runtime: Option<Duration>,
}
impl TimeObserver {
#[must_use]
pub fn new(name: &'static str) -> Self {
Self {
name: name.to_string(),
start_time: Duration::from_secs(0),
last_runtime: None,
}
}
#[must_use]
pub fn last_runtime(&self) -> &Option<Duration> {
&self.last_runtime
}
}
impl Observer for TimeObserver {}
impl<EM, I, S, Z> HasExecHooks<EM, I, S, Z> for TimeObserver {
fn pre_exec(
&mut self,
_fuzzer: &mut Z,
_state: &mut S,
_mgr: &mut EM,
_input: &I,
) -> Result<(), Error> {
self.last_runtime = None;
self.start_time = current_time();
Ok(())
}
fn post_exec(
&mut self,
_fuzzer: &mut Z,
_state: &mut S,
_mgr: &mut EM,
_input: &I,
) -> Result<(), Error> {
self.last_runtime = Some(current_time() - self.start_time);
Ok(())
}
}
impl Named for TimeObserver {
fn name(&self) -> &str {
&self.name
}
}
#[cfg(feature = "std")]
#[cfg(test)]
mod tests {
use crate::{
bolts::tuples::{tuple_list, tuple_list_type, Named},
observers::{StdMapObserver, TimeObserver},
};
static mut MAP: [u32; 4] = [0; 4];
#[test]
fn test_observer_serde() {
let obv = tuple_list!(
TimeObserver::new("time"),
StdMapObserver::new("map", unsafe { &mut MAP })
);
let vec = postcard::to_allocvec(&obv).unwrap();
println!("{:?}", vec);
let obv2: tuple_list_type!(TimeObserver, StdMapObserver<u32>) =
postcard::from_bytes(&vec).unwrap();
assert_eq!(obv.0.name(), obv2.0.name());
}
}