Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
# Temporarily replaced macos-latest with macos-14.
# See https://github.com/WebAssembly/wabt/issues/2654
os: [ubuntu-latest, macos-14, windows-latest]
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/setup-python@v5
with:
Expand All @@ -45,7 +43,7 @@ jobs:
if: matrix.os == 'ubuntu-latest'
- name: install ninja (osx)
run: brew install ninja
if: startsWith(matrix.os, 'macos-')
if: matrix.os == 'macos-latest'
- name: install ninja (win)
run: choco install ninja
if: matrix.os == 'windows-latest'
Expand Down
30 changes: 26 additions & 4 deletions wasm2c/wasm-rt.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,13 +572,35 @@ typedef struct {
} wasm_rt_jmp_buf;

#ifndef _WIN32
#define WASM_RT_SETJMP_SETBUF(buf) sigsetjmp(buf, 1)
#define WASM_RT_SETJMP_TRAP_SETBUF(buf) sigsetjmp(buf, 1)

/**
* On macOS XNU, there is a bug where nested `sigsetjmp` and `siglongjmp`
* across threads that have an allocated alternate signal stack (`SS_ONSTACK`)
* will erroneously cause the kernel to preserve the `SS_ONSTACK` flag in the
* thread state. This happens because `siglongjmp` fails to call `_sigunaltstack`
* to clear the kernel state, even if the exception did not originate from
* the signal handler, leading to an assertion failure when trying to free
* the alternate signal stack.
*
* To bypass this, we use `sigsetjmp(buf, 0)` for Wasm exceptions. Since Wasm
* exceptions are purely for control flow and do not need to restore signal
* masks (unlike Wasm trap handlers recovering from a SIGSEGV), avoiding the
* signal mask prevents XNU from applying the buggy `SS_ONSTACK` persistence.
*
* See: https://github.com/WebAssembly/wabt/issues/2654
* See: https://github.com/golang/go/issues/44501
*/
#define WASM_RT_SETJMP_EXN_SETBUF(buf) sigsetjmp(buf, 0)
#else
#define WASM_RT_SETJMP_SETBUF(buf) setjmp(buf)
#define WASM_RT_SETJMP_TRAP_SETBUF(buf) setjmp(buf)
#define WASM_RT_SETJMP_EXN_SETBUF(buf) setjmp(buf)
#endif

#define WASM_RT_SETJMP(buf) \
((buf).initialized = true, WASM_RT_SETJMP_SETBUF((buf).buffer))
((buf).initialized = true, WASM_RT_SETJMP_TRAP_SETBUF((buf).buffer))
#define WASM_RT_SETJMP_EXN(buf) \
((buf).initialized = true, WASM_RT_SETJMP_EXN_SETBUF((buf).buffer))

#ifndef _WIN32
#define WASM_RT_LONGJMP_UNCHECKED(buf, val) siglongjmp(buf, val)
Expand All @@ -604,7 +626,7 @@ WASM_RT_NO_RETURN void wasm_rt_trap(wasm_rt_trap_t);
/** Return a human readable error string based on a trap type. */
const char* wasm_rt_strerror(wasm_rt_trap_t trap);

#define wasm_rt_try(target) WASM_RT_SETJMP(target)
#define wasm_rt_try(target) WASM_RT_SETJMP_EXN(target)

/** WebAssembly's default page size (64 KiB) */
#define WASM_DEFAULT_PAGE_SIZE 65536
Expand Down
Loading