wasm3 / node-wasm-trace

Instruments wasm files and traces execution
MIT License
32 stars 6 forks source link
debugging trace tracer wasi webassembly

wasm-trace

Instruments wasm files using Binaryen.js, runs them and traces execution

Areas of application

Install

npm install -g wasm-trace

Example

$ wasm-trace -ELM ./test/hello.wasm
[tracer] Instrumenting and optimizing...
[tracer] Running WASI...
Hello WebAssembly!
[tracer] Processing...

The trace can be found in trace.log:

     2 |     | enter _start {
     0 | i32 |   set    0 70784
    43 |     |   enter __wasilibc_init_preopen {
     6 |     |     enter malloc {
    38 | i32 |       get    0 16
    23 |     |       enter dlmalloc {
    39 | i32 |         set    1 70768
    40 | i32 |         get    0 16
     8 | i32 |         load   0+3424 0
    41 | i32 |         set    2 0
       |     |         ...

How it works

  1. Analyzes the input wasm file (checks for WASI, instrumentation, etc.)
  2. Instruments it using Binaryen.js
  3. Runs the instrumented file with injected instrumentation handlers
  4. Writes CSV trace file
  5. Post-processes the CSV trace file and produces a structured log file

Following Binaryen instrumentation passes are supported:

Instrumentation, execution and post-processing stages are completely decoupled.
You can run each step separately:

  1. Add instrumentation to a wasm binary file.

    node ./wasm-trace.js -ELM --save-wasm=./instrumented.wasm ./test/hello.wasm

    Or using Binaryen directly:

    wasm-opt --log-execution --instrument-memory --instrument-locals ./test/hello.wasm -o ./instrumented.wasm
  2. Run instrumented wasm file.
    For Node.js, this step currently requires enabling bigint and wasi features:

    node --experimental-wasm-bigint --experimental-wasi-unstable-preview1 ./wasm-trace.js --save-csv=trace.csv ./instrumented.wasm

    Or using Wasm3:

    wasm3 ./instrumented.wasm        # The trace will be written to wasm3_trace.csv
  3. Analyze/post-process the CSV trace file.

    node ./wasm-trace.js --process=trace.csv ./instrumented.wasm        # Produces trace.log

Usage

wasm-trace.js [options] <file> [args..]

Options:
  --execution, -E    Instrument execution  [boolean]
  --locals, -L       Instrument locals  [boolean]
  --memory, -M       Instrument memory  [boolean]
  --optimize, --opt  Optimize (use --no-opt to disable)  [boolean] [default: true]
  --output, -o       Output filename  [string] [default: "trace.log"]
  --save-wasm        Save instrumented wasm to ...  [string]
  --save-csv         Save CSV log file to ...  [string]
  --process          Process CSV log file  [string]
  --invoke, -i       Invoke a specified function  [string]
  --version          Show version number  [boolean]
  --help             Show help  [boolean]

Examples:
  wasm-trace.js -E ./test/hello.wasm                     Instrument, run and trace WASI app
  wasm-trace.js -ELM --invoke=fib ./test/fib32.wasm 20   Instrument, run and trace plain wasm file
  wasm-trace.js ./test/hello.instrumented.wasm           Run pre-instrumented wasm file
  wasm-trace.js --process=trace.csv ./instrumented.wasm  Just process an existing CSV trace file