diff --git a/fuzzers/FRET/benchmark/Snakefile b/fuzzers/FRET/benchmark/Snakefile index 0ce963b712..859cd6707d 100644 --- a/fuzzers/FRET/benchmark/Snakefile +++ b/fuzzers/FRET/benchmark/Snakefile @@ -2,7 +2,7 @@ import csv import os def_flags="--no-default-features --features std,snapshot_restore,singlecore,restarting,run_until_saturation" remote="timedump_253048_1873f6_all/" -RUNTIME=120 +RUNTIME=30 TARGET_REPS_A=2 TARGET_REPS_B=2 NUM_NODES=2 @@ -143,7 +143,7 @@ rule run_bench: "build/{target}.elf", "bins/target_{fuzzer}" output: - multiext("timedump/{fuzzer}/{target}.{num}", "", ".log") # , ".case" + multiext("timedump/{fuzzer}/{target}#{num}", ".time", ".log") # , ".case" run: with open('target_symbols.csv') as csvfile: reader = csv.DictReader(csvfile) @@ -157,21 +157,9 @@ rule run_bench: bkp=line['return_function'] script=""" mkdir -p $(dirname {output[0]}) - # export KERNEL=$(pwd)/{input[0]} - # export FUZZ_MAIN={fuzz_main} - # export FUZZ_INPUT={fuzz_input} - # export FUZZ_INPUT_LEN={fuzz_len} - # export BREAKPOINT={bkp} - # export SEED_RANDOM={wildcards.num} - export TIME_DUMP=$(pwd)/{output[0]} - export CASE_DUMP=$(pwd)/{output[0]}.case - export TRACE_DUMP=$(pwd)/{output[0]}.trace - # export FUZZ_ITERS={RUNTIME} - export FUZZER=$(pwd)/{input[1]}/debug/fret set +e - # ../fuzzer.sh > {output[1]} 2>&1 - echo $(pwd)/{input[1]}/debug/fret -k {input[0]} -c ./target_symbols.csv fuzz -t {RUNTIME} -s {wildcards.num} - $(pwd)/{input[1]}/debug/fret -k {input[0]} -c ./target_symbols.csv fuzz -t {RUNTIME} -s {wildcards.num} > {output[1]} 2>&1 + echo $(pwd)/{input[1]}/debug/fret -n $(pwd)/timedump/{wildcards.fuzzer}/{wildcards.target}#{wildcards.num} -t -a -r -k {input[0]} -c ./target_symbols.csv fuzz -t {RUNTIME} -s {wildcards.num} + $(pwd)/{input[1]}/debug/fret -n $(pwd)/timedump/{wildcards.fuzzer}/{wildcards.target}#{wildcards.num} -t -a -r -k {input[0]} -c ./target_symbols.csv fuzz -t {RUNTIME} -s {wildcards.num} > {output[1]} 2>&1 exit 0 """ if wildcards.fuzzer.find('random') >= 0: @@ -183,10 +171,10 @@ rule run_showmap: "{remote}build/{target}.elf", "bins/target_showmap", "bins/target_showmap_int", - "{remote}timedump/{fuzzer}/{target}.{num}.case" + "{remote}timedump/{fuzzer}/{target}#{num}.case" output: - "{remote}timedump/{fuzzer}/{target}.{num}.trace.ron", - "{remote}timedump/{fuzzer}/{target}.{num}.case.time", + "{remote}timedump/{fuzzer}/{target}#{num}.trace.ron", + "{remote}timedump/{fuzzer}/{target}#{num}.case.time", run: with open('target_symbols.csv') as csvfile: reader = csv.DictReader(csvfile) @@ -205,16 +193,9 @@ rule run_showmap: script="export FUZZER=$(pwd)/{input[1]}/debug/fret\n" script+=""" mkdir -p $(dirname {output}) - export KERNEL=$(pwd)/{input[0]} - export FUZZ_MAIN={fuzz_main} - export FUZZ_INPUT={fuzz_input} - export FUZZ_INPUT_LEN={fuzz_len} - export BREAKPOINT={bkp} - export TRACE_DUMP=$(pwd)/{output[0]} - export DO_SHOWMAP=$(pwd)/{input[3]} - export TIME_DUMP=$(pwd)/{output[1]} set +e - ../fuzzer.sh + echo $(pwd)/{input[1]}/debug/fret -n $(pwd)/timedump/{wildcards.fuzzer}/{wildcards.target}#{wildcards.num} -t -a -r -k {input[0]} -c ./target_symbols.csv showmap -i {input[3]} + $(pwd)/{input[1]}/debug/fret -n $(pwd)/timedump/{wildcards.fuzzer}/{wildcards.target}#{wildcards.num} -t -a -r -k {input[0]} -c ./target_symbols.csv showmap -i {input[3]} exit 0 """ if wildcards.fuzzer.find('random') >= 0: diff --git a/fuzzers/FRET/src/clock.rs b/fuzzers/FRET/src/clock.rs index 2f0d59afb7..55b519ff87 100644 --- a/fuzzers/FRET/src/clock.rs +++ b/fuzzers/FRET/src/clock.rs @@ -152,7 +152,7 @@ where v.1 = (self.end_tick - self.start_tick, timestamp); } if v.0.len() >= 100 { - if let Ok(td) = env::var("TIME_DUMP") { + if let Ok(td) = env::var("DUMP_TIMES") { let mut file = OpenOptions::new() .read(true) .write(true) diff --git a/fuzzers/FRET/src/fuzzer.rs b/fuzzers/FRET/src/fuzzer.rs index dc1e2dccfa..833c6cd7c8 100644 --- a/fuzzers/FRET/src/fuzzer.rs +++ b/fuzzers/FRET/src/fuzzer.rs @@ -95,6 +95,22 @@ struct Cli { #[arg(short, long, value_name = "FILE")] config: PathBuf, + /// Sets the prefix of dumed files + #[arg(short='n', long, value_name = "FILENAME")] + dump_name: Option, + + /// do time dumps + #[arg(short='t', long)] + dump_times: bool, + + /// do worst-case dumps + #[arg(short='a', long)] + dump_cases: bool, + + /// do trace dumps (if supported) + #[arg(short='r', long)] + dump_traces: bool, + #[command(subcommand)] command: Commands, } @@ -120,6 +136,25 @@ enum Commands { } } +macro_rules! do_dump_case { + ( $s:expr,$c:expr) => { + println!("Dumping worst case to {:?}", $c); + let corpus = $s.corpus(); + let mut worst = Duration::new(0,0); + let mut worst_input = None; + for i in 0..corpus.count() { + let tc = corpus.get(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().bytes().to_owned()); + worst = tc.exec_time().expect("Testcase missing duration"); + } + } + if let Some(wi) = worst_input { + fs::write(&$c,wi).expect("Failed to write worst corpus element"); + } + } +} + fn env_from_config(kernel : &PathBuf, path : &PathBuf) { let is_csv = path.as_path().extension().map_or(false, |x| x=="csv"); if !is_csv { @@ -152,6 +187,12 @@ pub fn fuzz() { let cli = Cli::parse(); env_from_config(&cli.kernel, &cli.config); unsafe {FUZZ_START_TIMESTAMP = SystemTime::now();} + if let Some(n) = &cli.dump_name { + env::set_var("DUMP_NAME", n); + if cli.dump_times { + env::set_var("DUMP_TIMES", n.with_extension("time")); + } + } let mut starttime = std::time::Instant::now(); if let Ok(s) = env::var("FUZZ_SIZE") { str::parse::(&s).expect("FUZZ_SIZE was not a number"); @@ -367,7 +408,7 @@ pub fn fuzz() { #[cfg(all(feature = "systemstate",not(any(feature = "feed_systemgraph",feature = "feed_systemtrace"))))] let mut feedback = feedback_or!( feedback, - DumpSystraceFeedback::with_dump(env::var("TRACE_DUMP").ok().map(PathBuf::from)) + DumpSystraceFeedback::with_dump(if cli.dump_traces {cli.dump_name.clone().map(|x| x.with_extension("trace.ron"))} else {None}) ); #[cfg(feature = "feed_systemtrace")] let mut feedback = feedback_or!( @@ -473,7 +514,8 @@ pub fn fuzz() { }; fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, BytesInput::new(show_input)) .unwrap(); - if let Ok(td) = env::var("TIME_DUMP") { + if cli.dump_times { + let td = cli.dump_name.clone().expect("Dump name not give").with_extension("case.time"); let mut file = OpenOptions::new() .read(true) .write(true) @@ -553,7 +595,7 @@ pub fn fuzz() { { { let mut dumper = |marker : String| { - if let Ok(td) = env::var("TIME_DUMP") { + if let Ok(td) = env::var("DUMP_TIMES") { let mut file = OpenOptions::new() .read(true) .write(true) @@ -567,26 +609,8 @@ pub fn fuzz() { } } if let Ok(td) = env::var("CASE_DUMP") { - println!("Dumping worst case to {:?}", td); - 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(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().bytes().to_owned()); - worst = tc.exec_time().expect("Testcase missing duration"); - } - } - match worst_input { - Some(wi) => { - // let cd = format!("{}.case",&td); - let mut cd = td.clone(); - cd.push_str(&marker); - fs::write(&cd,wi).expect("Failed to write worst corpus element"); - }, - None => (), - } + let cd = cli.dump_name.clone().expect("Dump name not give").with_extension("time"); + do_dump_case!(state,cd); #[cfg(feature = "feed_systemgraph")] { let mut gd = String::from(&td); @@ -621,25 +645,8 @@ pub fn fuzz() { last=after; } if let Ok(td) = env::var("CASE_DUMP") { - println!("Dumping worst case to {:?}", td); - 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(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().bytes().to_owned()); - worst = tc.exec_time().expect("Testcase missing duration"); - } - } - match worst_input { - Some(wi) => { - // let cd = format!("{}.case",&td); - let cd = td.clone(); - fs::write(&cd,wi).expect("Failed to write worst corpus element"); - }, - None => (), - } + let cd = cli.dump_name.clone().expect("Dump name not give").with_extension("time"); + do_dump_case!(state,cd); #[cfg(feature = "feed_systemgraph")] { let mut gd = String::from(&td); @@ -662,7 +669,7 @@ pub fn fuzz() { } } } - if let Ok(td) = env::var("TIME_DUMP") { + if let Ok(td) = env::var("DUMP_TIMES") { let mut file = OpenOptions::new() .read(true) .write(true) @@ -675,42 +682,23 @@ pub fn fuzz() { } } } - if let Ok(td) = env::var("CASE_DUMP") { - println!("Dumping worst case to {:?}", td); - 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(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().bytes().to_owned()); - worst = tc.exec_time().expect("Testcase missing duration"); - } - } - match worst_input { - Some(wi) => { - // let cd = format!("{}.case",&td); - let cd = td.clone(); - fs::write(&cd,wi).expect("Failed to write worst corpus element"); - }, - None => (), - } + if cli.dump_cases { + let cd = cli.dump_name.clone().expect("Dump name not give").with_extension("case"); + do_dump_case!(state,cd); #[cfg(feature = "feed_systemgraph")] { - let mut gd = String::from(&td); - gd.push_str(".graph"); + let mut gd = cli.dump_name.clone().expect("Dump name not give").with_extension("graph"); if let Some(md) = state.named_metadata_map_mut().get_mut::("SysMap") { fs::write(&gd,ron::to_string(&md).expect("Failed to serialize graph")).expect("Failed to write graph"); } } { - let mut gd = String::from(&td); + let gd = cli.dump_name.clone().expect("Dump name not give").with_extension("toprated"); if let Ok(md) = state.metadata_mut::() { let mut uniq: Vec = md.map.values().map(|x| x.clone()).collect(); uniq.sort(); uniq.dedup(); - gd.push_str(&format!(".{}.toprated", uniq.len())); - fs::write(&gd,ron::to_string(&md.map).expect("Failed to serialize metadata")).expect("Failed to write graph"); + fs::write(&gd,ron::to_string(&(uniq.len(),&md.map)).expect("Failed to serialize metadata")).expect("Failed to write graph"); } } }