whamm!
Debugging Wasm? Put some whamm! on it!
whamm! is a tool for "Wasm Application Monitoring and Manipulation"[^silent-h], a DSL inspired by DTrace's D language.
[^silent-h]: The 'h' is silent.
Getting Started
Take a look at the official whamm! book for how to get started with this tool.
Build
# Debug build
make
# Release build
make release
Run
Configure whamm
To configure whamm:
- Build the binary:
cargo build - Add the binary to your
PATH, located at:target/debug/whamm - Configure
WHAMM_HOMEenvironment variable, should point to the base directory of the cloned repository. - Test the setup: you should be able to run
whamm --helpandwhamm info -fv --rule "wasm:opcode:i32.load:before"from anywhere
Instrument with Bytecode Rewriting
To instrument an application with a whamm script (there are example Scripts in tests/scripts folder):
cargo run -- instr --app <path_to_app.wasm> --script <path_to_script.mm> -o path/to/output.wasm
To run an instrumented application, do the following:
# Build the whamm-core library
cd whamm_core
cargo build --target wasm32-wasip1 --release
ls -al ./target/wasm32-wasip1/release/whamm_core.wasm
cd ..
# To run via the Rust crate
cd wasmtime-runner
# Should print the report data when the app is finished executing
WASM_MODULE=path/to/output.wasm cargo run
# You can also just run wasmtime directly on the CLI...whatever you choose
wasmtime run --env TO_CONSOLE=true --preload whamm_core=path/to/whamm_core.wasm path/to/output.wasm
Instrument with an Engine Monitor Module
To instrument an application with a whamm script (there are example Scripts in tests/scripts folder):
cargo run -- instr --script <path_to_script.mm> --wei -o path/to/output.wasm
To run an instrumented application, do the following:
# Build the whamm-core library
cd whamm_core
cargo build --target wasm32-wasip1 --release
ls -al ./target/wasm32-wasip1/release/whamm_core.wasm
cd ..
whamm instr --script path/to/whamm/script.mm --wei -o path/to/output.wasm
# (See above for the path to the whamm_core library)
wizeng --env=TO_CONSOLE=true --expose=wizeng --monitors=path/to/output.wasm+path/to/whamm_core.wasm path/to/app.wasm
Utilities/helpful info
To specify log level:
RUST_LOG={ error | warn | info | debug | trace | off } cargo run -- --app <path_to_app.wasm> --script <path_to_script.mm>
To use the utility that provides information about match rule bound vars/functions that can be leveraged by a probe's logic/predicate:
cargo run -- info --rule "<match_rule_glob>" # e.g. "wasm:opcode:br:*"
Test
In order to run the tests, a WebAssembly interpreter must be configured. The supported interpreters are:
- the Wizard engine interpreter. https://github.com/titzer/wizard-engine/tree/master
- the Wasm reference interpreter. https://github.com/WebAssembly/spec/tree/main/interpreter
The Wizard Engine execution script must also be configured, located at: https://github.com/titzer/wizard-engine/tree/master
How to build the Wizard GH project to acquire these binaries:
- Install OCaml
- Download
progressand ensure theprogressbinary is on yourPATH - Download and build
wizeng- After running
make -j, the binariesspectest.*should be located atwizard-engine/bin/spectest.*
- After running
- Build the Wasm reference interpreter through the Wizard repo, after running the below commands, the binary
wasmshould be located atwizard-engine/test/wasm-spec/repos/spec/interpreter/wasm# Configure OCaml # Build the wasm ref interpreter
The interpreter binaries must be runnable using the following commands (this can be done by placing symbolic links to the respective binaries):
- For Wizard:
./output/tests/engines/wizard-spectest - For Wasm-Ref:
./output/tests/engines/wasm
The Wizard binary must be runnable using the following command (this can be done by placing symbolic links to the respective binaries):
- For
wizeng:./output/tests/engines/wizeng
To run tests:
cargo test
cargo test parser # Only run the tests for the `parser` module
cargo test -- --nocapture # With stdout tracing
Available Packages
NOTE: There was discussion for moving the probe mode to the front of the match rule (e.g. mode:provider:package:event);
however, after thinking through this, I don't think it makes sense until I have a firmer grasp on the types of modes we will
have in this language. If there are more than before/after/alt (that are event-specific), then it would be confusing from a
language-intuition perspective. This is primarily because reading through the spec implies a movement from higher-to-lower
levels of granularity, everything being provided by what proceeds it. If we were to move mode to the front, but then have
event-specific options, this property would no longer hold.
Currently available:
wasm:opcode
To be added:
threadoperation eventsgcoperation eventsfunctionenter/exit/unwind eventsmemoryaccess (read/write) eventstableaccess (read/write) eventscomponentoperation eventswasm:begin/wasm:endeventstrapsexceptionthrow/rethrow/catch events
Example:
wasi:http:send_req:altwasm:opcode:call:altwasm:fn:enter:before
The book
If you are wanting to deploy the book locally, use the following commands:
# Install the mdbook cargo package
# Start the mdbook server and open the URL
This can be useful for offline learning OR for debugging documentation while doing updates (any local changes will automatically be updated in the served book pages).