dump intermediate cases

This commit is contained in:
Alwin Berger 2025-02-18 16:25:57 +01:00
parent 107ccf03a8
commit 64d1151e96
2 changed files with 44 additions and 13 deletions

View File

@ -371,7 +371,7 @@ let run_client = |state: Option<_>, mut mgr, _core_id| {
#[cfg(all(feature = "observe_systemstate"))]
let mut feedback = feedback_or!(
feedback,
DumpSystraceFeedback::<FreeRTOSSystem>::with_dump(if cli.dump_traces {cli.dump_name.clone().map(|x| x.with_extension("trace.ron"))} else {None})
DumpSystraceFeedback::<FreeRTOSSystem>::with_dump(if cli.dump_traces {cli.dump_name.clone()} else {None})
);
#[cfg(feature = "trace_stg")]
let mut feedback = feedback_or!(

View File

@ -4,12 +4,15 @@ use libafl::{
feedbacks::Feedback,
observers::ObserversTuple,
prelude::{State, UsesInput},
state::MaybeHasClientPerfMonitor,
state::{HasCorpus, MaybeHasClientPerfMonitor},
Error,
corpus::Corpus,
inputs::Input,
};
use libafl::events::EventFirer;
use libafl_bolts::Named;
use std::path::PathBuf;
use std::time::{Duration, Instant};
use super::target_os::TargetSystem;
use std::borrow::Cow;
@ -28,16 +31,19 @@ where
name: Cow<'static, str>,
dumpfile: Option<PathBuf>,
phantom: PhantomData<SYS>,
init_time: Instant,
last_dump: Option<Instant>,
}
impl<S, SYS> StateInitializer<S> for DumpSystraceFeedback<SYS> where SYS: TargetSystem {}
impl<EM, I, OT, S, SYS> Feedback<EM, I, OT, S> for DumpSystraceFeedback<SYS>
where
S: State + UsesInput + MaybeHasClientPerfMonitor + HasMetadata,
S: State + UsesInput + MaybeHasClientPerfMonitor + HasMetadata + HasCorpus<Corpus: Corpus<Input=I>>,
EM: EventFirer<State = S>,
OT: ObserversTuple<I, S>,
SYS: TargetSystem,
I: Input,
{
fn is_interesting(
&mut self,
@ -50,16 +56,37 @@ where
where {
match &self.dumpfile {
Some(s) => {
let trace = state
.metadata::<SYS::TraceData>()
.expect("TraceData not found");
std::fs::write(
s,
ron::to_string(trace)
.expect("Error serializing hashmap"),
)
.expect("Can not dump to file");
self.dumpfile = None
let time_has_come = self.last_dump.map(|t| Instant::now()-t > Duration::from_secs(60)).unwrap_or(true);
if time_has_come {
self.last_dump = Some(Instant::now());
// Try dumping the worst case
let casename = s.with_extension(format!("at_{}h.case", (Instant::now()-self.init_time).as_secs()/60));
let corpus = state.corpus();
let mut worst = Duration::new(0,0);
let mut worst_input = None;
for i in 0..corpus.count() {
let tc = corpus.get(corpus.nth(i.into())).expect("Could not get element from corpus").borrow();
if worst < tc.exec_time().expect("Testcase missing duration") {
worst_input = Some(tc.input().as_ref().unwrap().clone());
worst = tc.exec_time().expect("Testcase missing duration");
}
}
if let Some(wi) = worst_input {
wi.to_file(casename);
}
// Try dumping the current case
let tracename = s.with_extension("trace.ron");
let trace = state
.metadata::<SYS::TraceData>()
.expect("TraceData not found");
std::fs::write(
tracename,
ron::to_string(trace)
.expect("Error serializing hashmap"),
)
.expect("Can not dump to file");
}
}
Option::None => {
()
@ -90,6 +117,8 @@ where
name: Cow::from("Dumpsystemstate".to_string()),
dumpfile: None,
phantom: PhantomData,
init_time: std::time::Instant::now(),
last_dump: None,
}
}
#[allow(unused)]
@ -98,6 +127,8 @@ where
name: Cow::from("Dumpsystemstate".to_string()),
dumpfile: dumpfile,
phantom: PhantomData,
init_time: std::time::Instant::now(),
last_dump: None,
}
}
}