Skip to content

Commit e8ffd4d

Browse files
authored
[wasm2c] Fix exception testing on macOS (#2716)
This commit addresses the assertion failures during exception testing in `wasm2c` on macOS: `Assertion failed: (!(ss.ss_flags & SS_ONSTACK) && "attempt to deallocate altstack while in use")` Exception handling in wasm2c uses `wasm_rt_try(target)` which mapped to `sigsetjmp(buf, 1)`. However, on macOS (XNU), performing nested `sigsetjmp(..., 1)` and `siglongjmp` across threads with an allocated alternate signal stack can erroneously cause the kernel to preserve the `SS_ONSTACK` flag in the thread state, even when the exception did not originate from the signal handler. Since WebAssembly exception handling relies strictly on `setjmp`/`longjmp` for control flow and does not need to restore signal masks (unlike stack exhaustion traps, which do need the mask to unblock `SIGSEGV`), the fix is to simply avoid saving the signal mask for exception boundaries. We split `WASM_RT_SETJMP_SETBUF` into two variants: - `WASM_RT_SETJMP_TRAP_SETBUF`: Uses `sigsetjmp(buf, 1)` for traps (safely handles `SIGSEGV`). - `WASM_RT_SETJMP_EXN_SETBUF`: Uses `sigsetjmp(buf, 0)` for Wasm exceptions (bypasses `SS_ONSTACK` bug). This also reverts commit 74cc83c (which temporarily disabled `macos-latest` in CI), as the tests now pass successfully. Fixes #2654
1 parent 10dcc58 commit e8ffd4d

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ jobs:
3030
runs-on: ${{ matrix.os }}
3131
strategy:
3232
matrix:
33-
# Temporarily replaced macos-latest with macos-14.
34-
# See https://github.com/WebAssembly/wabt/issues/2654
35-
os: [ubuntu-latest, macos-14, windows-latest]
33+
os: [ubuntu-latest, macos-latest, windows-latest]
3634
steps:
3735
- uses: actions/setup-python@v5
3836
with:
@@ -45,7 +43,7 @@ jobs:
4543
if: matrix.os == 'ubuntu-latest'
4644
- name: install ninja (osx)
4745
run: brew install ninja
48-
if: startsWith(matrix.os, 'macos-')
46+
if: matrix.os == 'macos-latest'
4947
- name: install ninja (win)
5048
run: choco install ninja
5149
if: matrix.os == 'windows-latest'

wasm2c/wasm-rt.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -572,13 +572,27 @@ typedef struct {
572572
} wasm_rt_jmp_buf;
573573

574574
#ifndef _WIN32
575-
#define WASM_RT_SETJMP_SETBUF(buf) sigsetjmp(buf, 1)
575+
#define WASM_RT_SETJMP_TRAP_SETBUF(buf) sigsetjmp(buf, 1)
576+
577+
/**
578+
* On macOS XNU, there is a bug where nested `sigsetjmp` and `siglongjmp`
579+
* across threads that have an allocated alternate signal stack (`SS_ONSTACK`)
580+
* will erroneously cause the kernel to preserve the `SS_ONSTACK` flag in the
581+
* thread state
582+
*
583+
* See: https://github.com/WebAssembly/wabt/issues/2654
584+
* See: https://github.com/golang/go/issues/44501
585+
*/
586+
#define WASM_RT_SETJMP_EXN_SETBUF(buf) sigsetjmp(buf, 0)
576587
#else
577-
#define WASM_RT_SETJMP_SETBUF(buf) setjmp(buf)
588+
#define WASM_RT_SETJMP_TRAP_SETBUF(buf) setjmp(buf)
589+
#define WASM_RT_SETJMP_EXN_SETBUF(buf) setjmp(buf)
578590
#endif
579591

580592
#define WASM_RT_SETJMP(buf) \
581-
((buf).initialized = true, WASM_RT_SETJMP_SETBUF((buf).buffer))
593+
((buf).initialized = true, WASM_RT_SETJMP_TRAP_SETBUF((buf).buffer))
594+
#define WASM_RT_SETJMP_EXN(buf) \
595+
((buf).initialized = true, WASM_RT_SETJMP_EXN_SETBUF((buf).buffer))
582596

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

607-
#define wasm_rt_try(target) WASM_RT_SETJMP(target)
621+
#define wasm_rt_try(target) WASM_RT_SETJMP_EXN(target)
608622

609623
/** WebAssembly's default page size (64 KiB) */
610624
#define WASM_DEFAULT_PAGE_SIZE 65536

0 commit comments

Comments
 (0)