diff options
author | Keith Winstein <keithw@cs.stanford.edu> | 2023-12-05 23:04:03 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-05 23:04:03 -0800 |
commit | 99c860c4baba73cfd3b816e53007ddcd9fa8cc07 (patch) | |
tree | 3c43415e7264b8fa00ffcf8ae962fa3583b32cfd | |
parent | 4ce790d24c8ed71a7d23e9a9b4a5fc4ba704d48e (diff) | |
download | wabt-99c860c4baba73cfd3b816e53007ddcd9fa8cc07.tar.gz wabt-99c860c4baba73cfd3b816e53007ddcd9fa8cc07.tar.bz2 wabt-99c860c4baba73cfd3b816e53007ddcd9fa8cc07.zip |
wasm2c runtime: fix mis-nesting of def'n of os_has_altstack_installed (#2346)
Also adds an RLBox-like CI test where the embedder takes responsibility for signal handling
Co-authored-by: wrv <wrv@utexas.edu>
-rw-r--r-- | .github/workflows/build.yml | 16 | ||||
-rwxr-xr-x | test/run-tests.py | 6 | ||||
-rw-r--r-- | test/spec-wasm2c-prefix.c | 59 | ||||
-rw-r--r-- | wasm2c/wasm-rt-impl.c | 25 | ||||
-rw-r--r-- | wasm2c/wasm-rt.h | 10 |
5 files changed, 99 insertions, 17 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 78fd7b89..f9926ff6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -167,3 +167,19 @@ jobs: run: cmake --build out --target run-c-api-tests - name: tests run: cmake --build out --target run-tests + build-rlbox: + name: rlbox + runs-on: ubuntu-latest + env: + USE_NINJA: "1" + WASM2C_CFLAGS: "-DWASM_RT_USE_MMAP=1 -DWASM_RT_SKIP_SIGNAL_RECOVERY=1 -DWASM_RT_USE_STACK_DEPTH_COUNT=0 -DWASM2C_TEST_EMBEDDER_SIGNAL_HANDLING" + steps: + - uses: actions/setup-python@v1 + with: + python-version: '3.x' + - uses: actions/checkout@v1 + with: + submodules: true + - run: sudo apt-get install ninja-build + - run: make clang-debug + - run: ./test/run-tests.py --exclude-dir memory64 diff --git a/test/run-tests.py b/test/run-tests.py index 3f995e2b..2eb7ebbf 100755 --- a/test/run-tests.py +++ b/test/run-tests.py @@ -928,7 +928,10 @@ def main(args): action='store_true') parser.add_argument('patterns', metavar='pattern', nargs='*', help='test patterns.') + parser.add_argument('--exclude-dir', action='append', default=[], + help='directory to exclude.') options = parser.parse_args(args) + exclude_dirs = options.exclude_dir if options.jobs != 1: if options.fail_fast: @@ -937,7 +940,6 @@ def main(args): parser.error('--stop-interactive only works with -j1') if options.patterns: - exclude_dirs = [] pattern_re = '|'.join( fnmatch.translate('*%s*' % p) for p in options.patterns) else: @@ -945,7 +947,7 @@ def main(args): # By default, exclude wasi tests because WASI support is not include # by int the build by default. # TODO(sbc): Find some way to detect the WASI support. - exclude_dirs = ['wasi'] + exclude_dirs += ['wasi'] test_names = FindTestFiles('.txt', pattern_re, exclude_dirs) diff --git a/test/spec-wasm2c-prefix.c b/test/spec-wasm2c-prefix.c index ab57e9b4..e107325c 100644 --- a/test/spec-wasm2c-prefix.c +++ b/test/spec-wasm2c-prefix.c @@ -363,11 +363,70 @@ static void init_spectest_module(w2c_spectest* instance) { wasm_rt_allocate_funcref_table(&instance->spectest_table, 10, 20); } +// POSIX-only test config where embedder handles signals instead of w2c runtime +#ifdef WASM2C_TEST_EMBEDDER_SIGNAL_HANDLING +#include <signal.h> + +static void posix_signal_handler(int sig, siginfo_t* si, void* unused) { + wasm_rt_trap((si->si_code == SEGV_ACCERR) ? WASM_RT_TRAP_OOB + : WASM_RT_TRAP_EXHAUSTION); +} + +static void posix_install_signal_handler(void) { + /* install altstack */ + stack_t ss; + ss.ss_sp = malloc(SIGSTKSZ); + ss.ss_flags = 0; + ss.ss_size = SIGSTKSZ; + if (sigaltstack(&ss, NULL) != 0) { + perror("sigaltstack failed"); + abort(); + } + + /* install signal handler */ + struct sigaction sa; + memset(&sa, '\0', sizeof(sa)); + sa.sa_flags = SA_SIGINFO | SA_ONSTACK; + sigemptyset(&sa.sa_mask); + sa.sa_sigaction = posix_signal_handler; + if (sigaction(SIGSEGV, &sa, NULL) != 0 || sigaction(SIGBUS, &sa, NULL) != 0) { + perror("sigaction failed"); + abort(); + } +} + +static void posix_cleanup_signal_handler(void) { + /* remove signal handler */ + struct sigaction sa; + memset(&sa, '\0', sizeof(sa)); + sa.sa_handler = SIG_DFL; + if (sigaction(SIGSEGV, &sa, NULL) != 0 || sigaction(SIGBUS, &sa, NULL)) { + perror("sigaction failed"); + abort(); + } + + /* disable and free altstack */ + stack_t ss; + ss.ss_flags = SS_DISABLE; + if (sigaltstack(&ss, NULL) != 0) { + perror("sigaltstack failed"); + abort(); + } + free(ss.ss_sp); +} +#endif + int main(int argc, char** argv) { +#ifdef WASM2C_TEST_EMBEDDER_SIGNAL_HANDLING + posix_install_signal_handler(); +#endif wasm_rt_init(); init_spectest_module(&spectest_instance); run_spec_tests(); printf("%u/%u tests passed.\n", g_tests_passed, g_tests_run); wasm_rt_free(); +#ifdef WASM2C_TEST_EMBEDDER_SIGNAL_HANDLING + posix_cleanup_signal_handler(); +#endif return g_tests_passed != g_tests_run; } diff --git a/wasm2c/wasm-rt-impl.c b/wasm2c/wasm-rt-impl.c index 72e4d66e..5f22d3bf 100644 --- a/wasm2c/wasm-rt-impl.c +++ b/wasm2c/wasm-rt-impl.c @@ -25,7 +25,8 @@ #include <stdlib.h> #include <string.h> -#if WASM_RT_INSTALL_SIGNAL_HANDLER && !defined(_WIN32) +#if (WASM_RT_INSTALL_SIGNAL_HANDLER || !WASM_RT_USE_STACK_DEPTH_COUNT) && \ + !defined(_WIN32) #include <signal.h> #include <unistd.h> #endif @@ -163,17 +164,7 @@ static void os_print_last_error(const char* msg) { perror(msg); } -#if WASM_RT_INSTALL_SIGNAL_HANDLER -static void os_signal_handler(int sig, siginfo_t* si, void* unused) { - if (si->si_code == SEGV_ACCERR) { - wasm_rt_trap(WASM_RT_TRAP_OOB); - } else { - wasm_rt_trap(WASM_RT_TRAP_EXHAUSTION); - } -} - #if !WASM_RT_USE_STACK_DEPTH_COUNT -/* These routines set up an altstack to handle SIGSEGV from stack overflow. */ static bool os_has_altstack_installed() { /* check for altstack already in place */ stack_t ss; @@ -184,7 +175,19 @@ static bool os_has_altstack_installed() { return !(ss.ss_flags & SS_DISABLE); } +#endif + +#if WASM_RT_INSTALL_SIGNAL_HANDLER +static void os_signal_handler(int sig, siginfo_t* si, void* unused) { + if (si->si_code == SEGV_ACCERR) { + wasm_rt_trap(WASM_RT_TRAP_OOB); + } else { + wasm_rt_trap(WASM_RT_TRAP_EXHAUSTION); + } +} +#if !WASM_RT_USE_STACK_DEPTH_COUNT +/* These routines set up an altstack to handle SIGSEGV from stack overflow. */ static void os_allocate_and_install_altstack(void) { /* verify altstack not already allocated */ assert(!g_alt_stack && diff --git a/wasm2c/wasm-rt.h b/wasm2c/wasm-rt.h index a79271e3..fe68aa1d 100644 --- a/wasm2c/wasm-rt.h +++ b/wasm2c/wasm-rt.h @@ -202,7 +202,7 @@ extern WASM_RT_THREAD_LOCAL uint32_t wasm_rt_call_stack_depth; #define WASM_RT_NO_RETURN __attribute__((noreturn)) #endif -#if defined(__APPLE__) && WASM_RT_INSTALL_SIGNAL_HANDLER +#if defined(__APPLE__) && !WASM_RT_USE_STACK_DEPTH_COUNT #define WASM_RT_MERGED_OOB_AND_EXHAUSTION_TRAPS 1 #else #define WASM_RT_MERGED_OOB_AND_EXHAUSTION_TRAPS 0 @@ -218,7 +218,7 @@ typedef enum { WASM_RT_TRAP_UNREACHABLE, /** Unreachable instruction executed. */ WASM_RT_TRAP_CALL_INDIRECT, /** Invalid call_indirect, for any reason. */ WASM_RT_TRAP_UNCAUGHT_EXCEPTION, /* Exception thrown and not caught. */ - WASM_RT_TRAP_UNALIGNED, /** Unaligned atomic instruction executed. */ + WASM_RT_TRAP_UNALIGNED, /** Unaligned atomic instruction executed. */ #if WASM_RT_MERGED_OOB_AND_EXHAUSTION_TRAPS WASM_RT_TRAP_EXHAUSTION = WASM_RT_TRAP_OOB, #else @@ -354,7 +354,8 @@ typedef struct { jmp_buf buffer; } wasm_rt_jmp_buf; -#if WASM_RT_INSTALL_SIGNAL_HANDLER && !defined(_WIN32) +#if (WASM_RT_INSTALL_SIGNAL_HANDLER || (!WASM_RT_USE_STACK_DEPTH_COUNT)) && \ + !defined(_WIN32) #define WASM_RT_SETJMP_SETBUF(buf) sigsetjmp(buf, 1) #else #define WASM_RT_SETJMP_SETBUF(buf) setjmp(buf) @@ -363,7 +364,8 @@ typedef struct { #define WASM_RT_SETJMP(buf) \ ((buf).initialized = true, WASM_RT_SETJMP_SETBUF((buf).buffer)) -#if WASM_RT_INSTALL_SIGNAL_HANDLER && !defined(_WIN32) +#if (WASM_RT_INSTALL_SIGNAL_HANDLER || (!WASM_RT_USE_STACK_DEPTH_COUNT)) && \ + !defined(_WIN32) #define WASM_RT_LONGJMP_UNCHECKED(buf, val) siglongjmp(buf, val) #else #define WASM_RT_LONGJMP_UNCHECKED(buf, val) longjmp(buf, val) |