FIXED This has been fixed in 130554 and is scheduled to be included in the Rust 1.83 release (it is currently available in the Rust 1.83-nightly build).
This repository contains tests and code to reproduce an issue with WASM/WASI
(preview 1) artifacts producing unexpected exit code values when using the Rust
Standary Library's
std::process::ExitCode
vs std::process::exit
.
There are two simple examples, exit-with-process
, which uses
std::process::exit
, and exit-with-exit-code
, which uses
std::process::ExitCode
. Each example may be executed on its own, compiled for
the host platform.
When compiled as a standard binary on the host system, the exit codes are
returned as expected. When compiled with wasm32-wasip1
, the use of ExitCode
results in the exit code of 1
, regardless of the value provided to
ExitCode::from
.
Note that the tool chain may be passed as an additional parameter to the just
commands listed below.
Build the two applications using either
$ just build-all-binary
or directly with
$ cargo rustc \
--manifest-path $BIN_NAME/Cargo.toml \
--release \
-- \
-C panic=abort \
-C opt-level=z \
-C codegen-units=1
where $BIN_NAME
is one of [exit-with-process, exit-with-exit-code]
.
These rustc
configuration options match what is being used when compiling the
code to wasm32-wasi
.
This example produces the exit code of 10
. On the host system, we see the
following.
$ cargo run --release --manifest-path ./exit-with-process/Cargo.toml
...
Exiting with code 10
$ echo $?
10
This example produces the exit code of 11
. On the host system, we see the
following.
$ cargo run --release --manifest-path ./exit-with-exit-code/Cargo.toml
...
Exiting with code 11
$ echo $?
11
When compiling these two examples using the wasm32-wasip1
target, the use of
std::process::exit
produces the same exit code as the host binary, as
expected. However, the use of std::process::ExitCode
results in the exit code
of 1, regardless of the value provided to ExitCode::from
.
These expectations have been provided as a set of unit tests in src/lib.rs
.
With the just command runner, run the following
$ just test
cargo rustc --manifest-path exit-with-process/Cargo.toml --release --target
wasm32-wasip1 -- # -C lto=y -C panic=abort -C opt-level=z -C codegen-units=1
Finished `release` profile [optimized] target(s) in 0.00s
cargo rustc --manifest-path exit-with-exit-code/Cargo.toml --release --target
wasm32-wasip1 -- # -C lto=y -C panic=abort -C opt-level=z -C codegen-units=1
Finished `release` profile [optimized] target(s) in 0.00s
cargo test
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.14s
Running unittests src/lib.rs
(target/debug/deps/wasm_wasi_return_code_reproducer-aed685ebe2675c4c)
running 3 tests
hello world
test tests::test_simple_wasm_return ... ok
Exiting with code 11`
Exiting with code 10
test tests::test_exit_with_exit_code ... FAILED
test tests::test_exit_with_process ... ok
failures:
---- tests::test_exit_with_exit_code stdout ----
thread 'tests::test_exit_with_exit_code' panicked at src/lib.rs:82:9:
assertion `left == right` failed
left: 11
right: 1
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
tests::test_exit_with_exit_code
test result: FAILED. 2 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out;
finished in 0.57s
error: test failed, to rerun pass `--lib`
error: Recipe `test` failed on line 19 with exit code 101
Without just
, the following will compile the two examples to wasm with
wasm32-wasip1
:
$ cargo rustc \
--manifest-path $BIN_NAME/Cargo.toml \
--release \
--target wasm32-wasip1 \
-- \
-C panic=abort \
-C opt-level=z \
-C codegen-units=1
where $BIN_NAME
is one of [exit-with-process, exit-with-exit-code]
.
The tests can be run using the standard cargo test
.
Looking at the WASM and decompiling it to WAT, we can see that in the ExitCode
case, the main
(marked as no_mangle
) function is returning a i32.const 1
:
(func $main (type 0) (result i32)
(local i32)
global.get $__stack_pointer
;; ...
global.set $__stack_pointer
i32.const 1)
rustc versions: rustc 1.80.1 (3f5fd8dd4 2024-08-06)
, rustc 1.81.0 (eeb90cda1 2024-09-04)
, rustc 1.82.0-beta.3 (4976ae480 2024-09-09)
, and
rustc 1.83.0-nightly (28e8f01c2 2024-09-17)
host OS:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.4 LTS
Release: 22.04
Codename: jammy