Skip to content

Commit

Permalink
cranelift: Use once_cell and cleanup some stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
afonso360 committed Sep 4, 2022
1 parent 46bca01 commit f89a591
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cranelift/interpreter/src/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1253,7 +1253,7 @@ impl<'a, V> ControlFlow<'a, V> {
}
}

#[derive(Error, Debug, PartialEq)]
#[derive(Error, Debug, PartialEq, Eq, Hash)]
pub enum CraneliftTrap {
#[error("user code: {0}")]
User(TrapCode),
Expand Down
2 changes: 1 addition & 1 deletion fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ cargo-fuzz = true

[dependencies]
anyhow = { version = "1.0.19" }
lazy_static = "1.4.0"
cranelift-codegen = { path = "../cranelift/codegen", features = ["incremental-cache"] }
cranelift-reader = { path = "../cranelift/reader" }
cranelift-wasm = { path = "../cranelift/wasm" }
Expand All @@ -20,6 +19,7 @@ cranelift-fuzzgen = { path = "../cranelift/fuzzgen" }
libfuzzer-sys = { version = "0.4.0", features = ["arbitrary-derive"] }
target-lexicon = "0.12"
smallvec = "1.6.1"
once_cell = "1.12.0"
wasmtime = { path = "../crates/wasmtime" }
wasmtime-fuzzing = { path = "../crates/fuzzing" }
component-test-util = { path = "../crates/misc/component-test-util" }
Expand Down
45 changes: 22 additions & 23 deletions fuzz/fuzz_targets/cranelift-fuzzgen.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#![no_main]

use lazy_static::lazy_static;
use libfuzzer_sys::arbitrary::{Arbitrary, Unstructured};
use libfuzzer_sys::fuzz_target;
use once_cell::sync::Lazy;
use std::collections::HashMap;
use std::sync::atomic::AtomicU64;
use std::sync::atomic::Ordering;
Expand All @@ -29,7 +29,8 @@ struct Statistics {
/// All inputs that we tried
pub total_inputs: AtomicU64,
/// Inputs that fuzzgen can build a function with
pub well_formed_inputs: AtomicU64,
/// This is also how many compiles we executed
pub valid_inputs: AtomicU64,

/// Total amount of runs that we tried in the interpreter
/// One fuzzer input can have many runs
Expand All @@ -40,27 +41,27 @@ struct Statistics {
/// How many runs resulted in a timeout?
pub run_result_timeout: AtomicU64,
/// How many runs ended with a trap?
pub run_result_trap: HashMap<TrapCode, AtomicU64>,
pub run_result_trap: HashMap<CraneliftTrap, AtomicU64>,
}

impl Statistics {
pub fn print(&self) {
let total_inputs = self.total_inputs.load(Ordering::SeqCst);
if total_inputs != 100000 {
if total_inputs != 50000 {
return;
}

let well_formed_inputs = self.well_formed_inputs.load(Ordering::SeqCst);
let valid_inputs = self.valid_inputs.load(Ordering::SeqCst);
let total_runs = self.total_runs.load(Ordering::SeqCst);
let run_result_success = self.run_result_success.load(Ordering::SeqCst);
let run_result_timeout = self.run_result_timeout.load(Ordering::SeqCst);

println!("== FuzzGen Statistics ====================");
println!("Total Inputs: {}", total_inputs);
println!(
"Well Formed Inputs: {} ({:.1}%)",
well_formed_inputs,
(well_formed_inputs as f64 / total_inputs as f64) * 100.0
"Valid Inputs: {} ({:.1}%)",
valid_inputs,
(valid_inputs as f64 / total_inputs as f64) * 100.0
);
println!("Total Runs: {}", total_runs);
println!(
Expand Down Expand Up @@ -89,16 +90,20 @@ impl Statistics {

impl Default for Statistics {
fn default() -> Self {
let mut run_result_trap = HashMap::new();
run_result_trap.insert(CraneliftTrap::Debug, AtomicU64::new(0));
run_result_trap.insert(CraneliftTrap::Resumable, AtomicU64::new(0));
for trapcode in TrapCode::non_user_traps() {
run_result_trap.insert(CraneliftTrap::User(*trapcode), AtomicU64::new(0));
}

Self {
total_inputs: AtomicU64::new(0),
well_formed_inputs: AtomicU64::new(0),
valid_inputs: AtomicU64::new(0),
total_runs: AtomicU64::new(0),
run_result_success: AtomicU64::new(0),
run_result_timeout: AtomicU64::new(0),
run_result_trap: TrapCode::non_user_traps()
.iter()
.map(|t| (*t, AtomicU64::new(0)))
.collect(),
run_result_trap,
}
}
}
Expand Down Expand Up @@ -163,9 +168,7 @@ fn build_interpreter(testcase: &TestCase) -> Interpreter {
interpreter
}

lazy_static! {
static ref STATISTICS: Statistics = Statistics::default();
}
static STATISTICS: Lazy<Statistics> = Lazy::new(Statistics::default);

fuzz_target!(|bytes: &[u8]| {
STATISTICS.print();
Expand All @@ -179,7 +182,7 @@ fuzz_target!(|bytes: &[u8]| {
}
};

STATISTICS.well_formed_inputs.fetch_add(1, Ordering::SeqCst);
STATISTICS.valid_inputs.fetch_add(1, Ordering::SeqCst);

// Native fn
let flags = {
Expand Down Expand Up @@ -208,19 +211,15 @@ fuzz_target!(|bytes: &[u8]| {
RunResult::Success(_) => {
STATISTICS.run_result_success.fetch_add(1, Ordering::SeqCst);
}
RunResult::Trap(CraneliftTrap::User(tc)) => {
STATISTICS.run_result_trap[&tc].fetch_add(1, Ordering::SeqCst);
RunResult::Trap(trap) => {
STATISTICS.run_result_trap[&trap].fetch_add(1, Ordering::SeqCst);
// We currently ignore inputs that trap the interpreter
// We could catch traps in the host run and compare them to the
// interpreter traps, but since we already test trap cases with
// wasm tests and wasm-level fuzzing, the amount of effort does
// not justify implementing it again here.
return;
}
RunResult::Trap(_) => {
// We never trigger these traps, and I'm not too bothered about counting them
unreachable!()
}
RunResult::Timeout => {
STATISTICS.run_result_timeout.fetch_add(1, Ordering::SeqCst);
// We probably generated an infinite loop, we can ignore this
Expand Down

0 comments on commit f89a591

Please sign in to comment.