Skip to content

Instantly share code, notes, and snippets.

@pepyakin
Created February 23, 2018 10:48
Show Gist options
  • Select an option

  • Save pepyakin/79de4ac26d20adcd9db64bf85ef34cba to your computer and use it in GitHub Desktop.

Select an option

Save pepyakin/79de4ac26d20adcd9db64bf85ef34cba to your computer and use it in GitHub Desktop.

Revisions

  1. pepyakin created this gist Feb 23, 2018.
    73 changes: 73 additions & 0 deletions wasm-reduce.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    When one try to run `wasm-reduce` on macOS machine, they will see something like this:

    ```
    wasm-reduce -v -f \
    --timeout=15 \
    --command="./predicate.sh" \
    --test=test.wasm \
    --working=working.wasm \
    ~/Downloads/wasm-collection-master/misc-valid/cv-wasm.wasm
    |wasm-reduce
    |input: /Users/pepyakin/Downloads/wasm-collection-master/misc-valid/cv-wasm.wasm
    |test: test.wasm
    |working: working.wasm
    |expected result:
    [ProgramResult] code: 32512 stdout:
    [/ProgramResult]
    |checking that command has different behavior on invalid binary
    |! running command on an invalid module should give different results
    [ProgramResult] code: 32512 stdout:
    [/ProgramResult]
    Fatal: |! stopping, as it is very unlikely reduction can succeed (use -f to ignore this check)
    ```

    It took quite some to figure out why my predicate script always returns status code 32512! : )
    Here is my story:

    It turns out that exit code 32512 is returned when command not found. As I found out later, it is not my predicate script is not found but the some `timeout` command which is [used by wasm-reduce](https://github.com/WebAssembly/binaryen/blob/d9692277357ba6fd67a7e25ce16934209d049033/src/tools/wasm-reduce.cpp#L62) to cap the execution time of the predicate script.

    Unfortunately, macOS comes without installed `timeout`. Fortunately, it can easily be installed with [brew](https://brew.sh): `brew install coreutils`.

    Since macOS comes with __some__ of coreutils programs installed, all these programs installed with names prepended by `g` (e.g `timeout` is `gtimeout`). Luckily, these are just aliases and programs with original names are installed in `/usr/local/opt/coreutils/libexec/gnubin`. So it is sufficient to just export new `PATH` that will use `coreutils`

    ```
    export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
    ```

    Next, after I try to launch reducing again, I stopped by this issue:

    ```
    |checking that command has different behavior on invalid binary
    |checking that command has expected behavior on canonicalized (read-written) binary
    |! failed to read and write the binary
    [ProgramResult] code: 32512 stdout:
    [/ProgramResult]
    ```

    So it seems that `wasm-reduce` trying to launch `wasm-opt` but for some reason can't.

    https://github.com/WebAssembly/binaryen/blob/d9692277357ba6fd67a7e25ce16934209d049033/src/tools/wasm-reduce.cpp#L685-L695

    That's weird since `wasm-opt` is on my `PATH` and `wasm-reduce` is launched from the same directory where `wasm-opt` is placed. Looking at the code,

    https://github.com/WebAssembly/binaryen/blob/6cf7343bffa3d485161e221b23dfacd9243dec68/src/support/path.h#L41-L55

    I was able to see that `wasm-reduce` is only trying to search `wasm-opt` at `BINARYEN_ROOT`.
    So adding another `export` might help:

    ```
    export BINARYEN_ROOT=~/dev/etc/binaryen
    ```

    After that was done, I was able to launch reducing! Hope this will help for future reducers (incl. me).

    Here is my `predicate.sh` for the reference:

    ```bash
    #!/bin/bash
    target/release/wasm-stack-height test.wasm result.wasm 2>&1 || exit 1
    wasm2wat result.wasm 2>&1 || exit 2
    ```