Turn off binaryen in fuzzing by default

... but turn it back on in CI by default. The `binaryen-sys` crate
builds binaryen from source, which is a drag on CI for a few reasons:

* This is quite large and takes a good deal of time to build
* The debug build directory for binaryen is 4GB large

In an effort to both save time and disk space on the builders this
commit adds a `binaryen` feature to the `wasmtime-fuzz` crate. This
feature is enabled specifically when running the fuzzers on CI, but it
is disabled during the typical `cargo test --all` command. This means
that the test builders should save an extra 4G of space and be a bit
speedier now that they don't build a giant wad of C++.

We'll need to update the OSS-fuzz integration to enable the `binaryen`
feature when executing `cargo fuzz build`, and I'll do that once this
gets closer to landing.
This commit is contained in:
Alex Crichton
2020-03-17 09:29:48 -07:00
parent ec90509387
commit b0cf8c021f
6 changed files with 22 additions and 12 deletions

View File

@@ -79,7 +79,7 @@ jobs:
- run: cargo install cargo-fuzz --vers "^0.7" - run: cargo install cargo-fuzz --vers "^0.7"
- run: cargo fetch - run: cargo fetch
working-directory: ./fuzz working-directory: ./fuzz
- run: cargo fuzz build --release --debug-assertions - run: cargo fuzz build --release --debug-assertions --features binaryen
# Our corpora are too large to run in full on every pull request, they just # Our corpora are too large to run in full on every pull request, they just
# take too long. Instead, we sample some of them and make sure that running # take too long. Instead, we sample some of them and make sure that running
# our fuzzers over the sampled inputs still works OK. # our fuzzers over the sampled inputs still works OK.

View File

@@ -9,7 +9,7 @@ version = "0.12.0"
[dependencies] [dependencies]
anyhow = "1.0.22" anyhow = "1.0.22"
arbitrary = { version = "0.4.0", features = ["derive"] } arbitrary = { version = "0.4.0", features = ["derive"] }
binaryen = "0.10.0" binaryen = { version = "0.10.0", optional = true }
env_logger = "0.7.1" env_logger = "0.7.1"
log = "0.4.8" log = "0.4.8"
rayon = "1.2.1" rayon = "1.2.1"

View File

@@ -8,20 +8,22 @@
//! wrapper over an external tool, such that the wrapper implements the //! wrapper over an external tool, such that the wrapper implements the
//! `Arbitrary` trait for the wrapped external tool. //! `Arbitrary` trait for the wrapped external tool.
#[cfg(feature = "binaryen")]
pub mod api; pub mod api;
use arbitrary::{Arbitrary, Unstructured}; use arbitrary::Arbitrary;
use std::fmt;
/// A Wasm test case generator that is powered by Binaryen's `wasm-opt -ttf`. /// A Wasm test case generator that is powered by Binaryen's `wasm-opt -ttf`.
#[derive(Clone)] #[derive(Clone)]
#[cfg(feature = "binaryen")]
pub struct WasmOptTtf { pub struct WasmOptTtf {
/// The raw, encoded Wasm bytes. /// The raw, encoded Wasm bytes.
pub wasm: Vec<u8>, pub wasm: Vec<u8>,
} }
impl fmt::Debug for WasmOptTtf { #[cfg(feature = "binaryen")]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { impl std::fmt::Debug for WasmOptTtf {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!( write!(
f, f,
"WasmOptTtf {{ wasm: wat::parse_str(r###\"\n{}\n\"###).unwrap() }}", "WasmOptTtf {{ wasm: wat::parse_str(r###\"\n{}\n\"###).unwrap() }}",
@@ -30,8 +32,9 @@ impl fmt::Debug for WasmOptTtf {
} }
} }
#[cfg(feature = "binaryen")]
impl Arbitrary for WasmOptTtf { impl Arbitrary for WasmOptTtf {
fn arbitrary(input: &mut Unstructured) -> arbitrary::Result<Self> { fn arbitrary(input: &mut arbitrary::Unstructured) -> arbitrary::Result<Self> {
crate::init_fuzzing(); crate::init_fuzzing();
let seed: Vec<u8> = Arbitrary::arbitrary(input)?; let seed: Vec<u8> = Arbitrary::arbitrary(input)?;
let module = binaryen::tools::translate_to_fuzz_mvp(&seed); let module = binaryen::tools::translate_to_fuzz_mvp(&seed);
@@ -39,7 +42,7 @@ impl Arbitrary for WasmOptTtf {
Ok(WasmOptTtf { wasm }) Ok(WasmOptTtf { wasm })
} }
fn arbitrary_take_rest(input: Unstructured) -> arbitrary::Result<Self> { fn arbitrary_take_rest(input: arbitrary::Unstructured) -> arbitrary::Result<Self> {
crate::init_fuzzing(); crate::init_fuzzing();
let seed: Vec<u8> = Arbitrary::arbitrary_take_rest(input)?; let seed: Vec<u8> = Arbitrary::arbitrary_take_rest(input)?;
let module = binaryen::tools::translate_to_fuzz_mvp(&seed); let module = binaryen::tools::translate_to_fuzz_mvp(&seed);

View File

@@ -110,7 +110,7 @@ pub fn compile(wasm: &[u8], strategy: Strategy) {
/// or aren't enabled for different configs, we should get the same results when /// or aren't enabled for different configs, we should get the same results when
/// we call the exported functions for all of our different configs. /// we call the exported functions for all of our different configs.
pub fn differential_execution( pub fn differential_execution(
ttf: &crate::generators::WasmOptTtf, wasm: &[u8],
configs: &[crate::generators::DifferentialConfig], configs: &[crate::generators::DifferentialConfig],
) { ) {
crate::init_fuzzing(); crate::init_fuzzing();
@@ -131,13 +131,13 @@ pub fn differential_execution(
}; };
let mut export_func_results: HashMap<String, Result<Box<[Val]>, Trap>> = Default::default(); let mut export_func_results: HashMap<String, Result<Box<[Val]>, Trap>> = Default::default();
log_wasm(&ttf.wasm); log_wasm(wasm);
for config in &configs { for config in &configs {
let engine = Engine::new(config); let engine = Engine::new(config);
let store = Store::new(&engine); let store = Store::new(&engine);
let module = match Module::new(&store, &ttf.wasm) { let module = match Module::new(&store, wasm) {
Ok(module) => module, Ok(module) => module,
// The module might rely on some feature that our config didn't // The module might rely on some feature that our config didn't
// enable or something like that. // enable or something like that.
@@ -283,6 +283,7 @@ fn assert_same_export_func_result(
} }
/// Invoke the given API calls. /// Invoke the given API calls.
#[cfg(feature = "binaryen")]
pub fn make_api_calls(api: crate::generators::api::ApiCalls) { pub fn make_api_calls(api: crate::generators::api::ApiCalls) {
use crate::generators::api::ApiCall; use crate::generators::api::ApiCall;

View File

@@ -34,15 +34,21 @@ name = "instantiate_translated"
path = "fuzz_targets/instantiate_translated.rs" path = "fuzz_targets/instantiate_translated.rs"
test = false test = false
doc = false doc = false
required-features = ['binaryen']
[[bin]] [[bin]]
name = "api_calls" name = "api_calls"
path = "fuzz_targets/api_calls.rs" path = "fuzz_targets/api_calls.rs"
test = false test = false
doc = false doc = false
required-features = ['binaryen']
[[bin]] [[bin]]
name = "differential" name = "differential"
path = "fuzz_targets/differential.rs" path = "fuzz_targets/differential.rs"
test = false test = false
doc = false doc = false
required-features = ['binaryen']
[features]
binaryen = ['wasmtime-fuzzing/binaryen']

View File

@@ -9,5 +9,5 @@ fuzz_target!(|data: (
generators::WasmOptTtf generators::WasmOptTtf
)| { )| {
let (lhs, rhs, wasm) = data; let (lhs, rhs, wasm) = data;
oracles::differential_execution(&wasm, &[lhs, rhs]); oracles::differential_execution(&wasm.wasm, &[lhs, rhs]);
}); });