wasm-shrink
A WebAssembly test case shrinker.
About
wasm-shrink
is a test case shrinker for WebAssembly. It shrinks a Wasm file
while preserving an interesting property (such as triggering a bug in your Wasm
compiler).
Usage
Install
$ cargo install wasm-tools
Writing a Predicate Script
The predicate script tells wasm-shrink
whether a Wasm file is "interesting" or
not, i.e. whether the Wasm file triggers the bug you are trying to isolate.
The interface between wasm-shrink
and a predicate script is simple:
-
The predicate script is given a Wasm file as its first and only argument.
-
The predicate script must exit with a zero status code if the Wasm file is interesting and a non-zero status code otherwise.
The predicate script must not depend on the current working directory nor that only one predicate script process is running at any given time.
Here is an example predicate script that could be used to track down a panic in Wasmtime that includes the panic message "assertion failed: invalid stack map":
#!/usr/bin/env bash
# Exit the script if any subcommand fails.
# The Wasm file is given as the first and only argument to the script.
WASM=
# Run the Wasm in Wasmtime and `grep` for our target bug's panic
# message.
|
Note that passing grep
the --quiet
flag makes it avoid its usual
match-printing behavior and exit with status code zero if there is any match
and non-zero if there is not any match. This is useful for predicate scripts.
Run
To run wasm-tools shrink
pass it the predicate and the initial test case:
The shrunken Wasm file will be written to shrunken.wasm
in this case, but if
the -o
flag is not given an output name is generated based on the initial test
case's name.
You can see all options by passing --help
:
Embed as a Library
wasm-shrink
is not only a command-line tool, it also defines a library to
allow programmatic usage.
First, add a dependency to your Cargo.toml
:
Then use the wasm_shrink::WasmShrink
builder to configure and run a shrinking
task:
use WasmShrink;
// Get the Wasm you want to shrink from somewhere.
let my_input_wasm: = todo!;
// Configure the shrinking task.
let shrink = default
// Give up on shrinking after 999 failed attempts to shrink a given
// Wasm test case any further.
.attempts;
// Run the configured shrinking task.
let info = shrink.run?;
// Get the shrunken Wasm and other information about the completed shrink
// task from the returned `ShrinkInfo`.
let shrunken_wasm = info.output;
For more details, see the documentation on
docs.rs
.