0.16.0: wasm32-emscripten fails to build because of default panic handler, recommended workaround?

Basically:

TL;DR: trying to build for wasm32-emscripten with 0.16.0 currently fails with:

/Users/floh/.zvm/0.16.0/lib/std/Io/Threaded.zig:15315:38: error: expected type 'os.linux.SIG__enum_1199', found 'u32'
        .{ .stopped = posix.W.STOPSIG(status) }
                      ~~~~~~~~~~~~~~~^~~~~~~~
/Users/floh/.zvm/0.16.0/lib/std/os/linux.zig:4036:8: note: enum declared here
} else enum(u32) {

…and:

/Users/floh/.zvm/0.16.0/lib/std/os/emscripten.zig:215:16: error: expected enum, found 'u32'
        return @enumFromInt(EXITSTATUS(s));
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~

@Moka has figured out that the problem can be worked around by overriding the panic handler:

const std = @import("std");
pub const panic = std.debug.FullPanic(wasmPanic);
fn wasmPanic(msg: []const u8, ret_addr: ?usize) noreturn {
    _ = msg; _ = ret_addr;
    @trap();
}

Questions:

  • is this an oversight in the stdlib (e.g. a Zig bug), or expected behaviour?
  • is the above override of the panic handler the recommended workaround, or is there a better way?

…e.g. there is this new --single-threaded cmdline option, can this be used to force the problematic std.Io.Threaded into single-threaded mode (and would that even help)? If yes, how is this used in via build.zig? (haven’t found anything in the std doc page).

Thanks!

4 Likes

Fixed by https://codeberg.org/ziglang/zig/pulls/31850 right?

The only thing left to do here is add CI coverage so it doesn’t happen again.

2 Likes

Ah yeah indeed, it’s fixed in the 0.17.0-dev nightly. Thanks!

For anyone who needs to compile for Emscripten using 0.16 instead of 0.17-dev, there are no simple fully functional workarounds. However, if you declare

pub const std_options_debug_io = std.Io.failing;
pub const panic = std.debug.no_panic;

in your root source file, your code should at least compile, with the caveat that most std APIs that try to write to stderr might panic (by virtue of calling the failing lockStderr() implementation, which contains an unreachable statement).

3 Likes

That looks like a good workaround, thanks! I’ll try that in my code and add a note to the readme.