Skip to content

Test wasm in CI with threads & unwinding #1039

Description

@alexcrichton

Proposal

Note: I'm not entirely sure if this is worthy of an MCP. Some brief discussion on Zulip led me to err on the side of being conservative and open one here. If the general consenus is "just send a PR" happy to close this and do that.

I'd like to propose a change to how WebAssembly targets are tested in CI. The specific changes are:

  • Change the target-that's-tested to wasm32-wasip3 instead of wasm32-wasip1
  • Test with -Cpanic=unwind in CI instead of the current default of -Cpanic=abort
  • When ready (~end of 2026) enable all tests that require threads

As a brief bit of history, WebAssembly was originally tested as wasm32-unknown-unknown with Node.js as the runner, but the debugging experience here was quite poor (the target can't print). Later this migrated to testing wasm32-wasip1 with I think first Node.js and then Wasmtime, but while debugging is better (prints work) the target is still quite limited compared to other "normal" targets. These limitations mean that much of the test suite does not run on wasm targets, such as the tests for the alloc crate and the std crate.

Testing with unwinding

The first major change I'd like to propose is to test WebAssembly with unwinding in CI. WebAssembly targets all default to -Cpanic=abort currently, primarily for historical reasons, and thus can't run anything using std::panic::catch_unwind for example. This proposal does not propose changing this default, wasm targets will still abort-on-panic, but this is proposing that CI tests binaries with -Cpanic=unwind. This technically loses coverage of what's shipping via rustup, but given the relative simplicity of -Cpanic=abort and the number of tests that require unwinding I'd expect that this would be greatly outweighed by the benefits of running more tests.

In local testing the best way I've come up with is to add a new bootstrap.toml option for whether wasm targets are unwinding by default. The test-various CI job/container would set this option, but nothing else would. Other attempts, such as setting RUSTFLAGS didn't work well because -Cpanic=unwind specified there overrode panic_abort being compiled with -Cpanic=abort which caused a lot of failures. This also in general felt like it integrated best into the build system & testing, but I'm of course not wed to this approach if there's a better one!

Testing with threads

The only WebAssembly target at this time which supports threads is wasm32-wasip1-threads, but that's not tested in CI and Wasmtime has removed support for this as well some versions back. Threads gate a large number of tests, however, such as most of what std does w.r.t. sockets. The proposal here is to use the cooperative threading of the wasm32-wasip3 target to support std::thread and run these tests.

This change is the primary reason for migrating to the wasm32-wasip3 target for testing in CI for rust-lang/rust. The main caveat for this is that threading is cooperative, aka not preemptive. Some various tests throughout the standard library require preemptive threading (e.g. an infinite loop reading an atomic waiting for another thread to set it). These tests will get edited to insert yield points on the wasm32-wasip3 platform, and most tests already contain a possible yield point for other platforms like sgx so wasm would fit in there.

Implementation

I would expect myself to be doing the work here, and I'd expect this, if accepted, to be split across two PRs:

  • The first PR would switch the target being tested to wasm32-wasip3 and would enable -Cpanic=unwind
    • This'd add a new bootstrap.toml option for changing the default panic strategy for wasm targets
    • This'd change the test-various container to build/test the wasm32-wasip3 target
    • This'd add the library/alloc suite of tests to what's tested on this target
    • This'd then adjust tests here-and-there to be passing, mostly just tweaking directives
  • The next PR would be later this year (~end of 2026) and would run tests with threads.
    • This is split out because cooperative threading is not yet stable in Wasmtime & Component Model land. I'd like to wait on that before having Rust test this in CI
    • The primary change here would be updating test directives to conclude that the wasm32-wasip3 target supports threads
    • The library/std test suite would be added to CI in addition to preexisting test suites.
    • Many test directives would get tweaked, some manual yields would get added, etc.

The rough shape of the first change is expected to look like alexcrichton/rust@86736fb, and the second change would look something like alexcrichton/rust@388ea29 (neither is fully complete, but that's what I'd expect)

Mentors or Reviewers

If you have a reviewer or mentor in mind for this work, mention them here. You can put your own name here if you are planning to mentor the work.

Process

The main points of the Major Change Process are as follows:

  • File an issue describing the proposal.
  • A compiler team member who is knowledgeable in the area can second by writing @rustbot second or kickoff a team FCP with @rfcbot fcp $RESOLUTION.
  • Once an MCP is seconded, the Final Comment Period begins.
    • Final Comment Period lasts for 10 days after all outstanding concerns are solved.
    • Outstanding concerns will block the Final Comment Period from finishing. Once all concerns are resolved, the 10 day countdown is restarted.
    • If no concerns are raised after 10 days since the resolution of the last outstanding concern, the MCP is considered approved.

You can read more about Major Change Proposals on forge.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-compilerAdd this label so rfcbot knows to poll the compiler teamfinal-comment-periodThe FCP has started, most (if not all) team members are in agreementmajor-changeA proposal to make a major change to rustcto-announceAnnounce this issue on triage meeting

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions