feat: sigfpe wasm traps

master
Sean McBride 3 years ago
parent 44d04f213a
commit 62a8dafa7c

@ -1 +1 @@
Subproject commit 4e6dc2a2918f787c610b00d4da13b7620d7d43c5
Subproject commit b465202070c09a82597f40c4adac84e7bcf6cb30

@ -54,60 +54,48 @@ rotr_u64(uint64_t n, uint64_t c_u64)
INLINE uint32_t
u32_div(uint32_t a, uint32_t b)
{
if (unlikely(b == 0)) sledge_abi__wasm_trap_raise(WASM_TRAP_ILLEGAL_ARITHMETIC_OPERATION);
return a / b;
}
INLINE uint32_t
u32_rem(uint32_t a, uint32_t b)
{
if (unlikely(b == 0)) sledge_abi__wasm_trap_raise(WASM_TRAP_ILLEGAL_ARITHMETIC_OPERATION);
return a % b;
}
INLINE int32_t
i32_div(int32_t a, int32_t b)
{
if (unlikely(b == 0 || (a == INT32_MIN && b == -1)))
sledge_abi__wasm_trap_raise(WASM_TRAP_ILLEGAL_ARITHMETIC_OPERATION);
return a / b;
}
INLINE int32_t
i32_rem(int32_t a, int32_t b)
{
if (unlikely(b == 0 || (a == INT32_MIN && b == -1)))
sledge_abi__wasm_trap_raise(WASM_TRAP_ILLEGAL_ARITHMETIC_OPERATION);
return a % b;
}
INLINE uint64_t
u64_div(uint64_t a, uint64_t b)
{
if (unlikely(b == 0)) sledge_abi__wasm_trap_raise(WASM_TRAP_ILLEGAL_ARITHMETIC_OPERATION);
return a / b;
}
INLINE uint64_t
u64_rem(uint64_t a, uint64_t b)
{
if (unlikely(b == 0)) sledge_abi__wasm_trap_raise(WASM_TRAP_ILLEGAL_ARITHMETIC_OPERATION);
return a % b;
}
INLINE int64_t
i64_div(int64_t a, int64_t b)
{
if (unlikely(b == 0 || (a == INT64_MIN && b == -1)))
sledge_abi__wasm_trap_raise(WASM_TRAP_ILLEGAL_ARITHMETIC_OPERATION);
return a / b;
}
INLINE int64_t
i64_rem(int64_t a, int64_t b)
{
if (unlikely(b == 0 || (a == INT64_MIN && b == -1)))
sledge_abi__wasm_trap_raise(WASM_TRAP_ILLEGAL_ARITHMETIC_OPERATION);
return a % b;
}

@ -107,5 +107,5 @@ current_sandbox_trap(enum sledge_abi__wasm_trap trapno)
assert(sandbox != NULL);
assert(sandbox->state == SANDBOX_RUNNING_USER || sandbox->state == SANDBOX_RUNNING_SYS);
longjmp(sandbox->ctxt.start_buf, trapno);
siglongjmp(sandbox->ctxt.start_buf, trapno);
}

@ -31,7 +31,7 @@ software_interrupt_mask_signal(int signal)
sigset_t set;
int return_code;
assert(signal == SIGALRM || signal == SIGUSR1);
assert(signal == SIGALRM || signal == SIGUSR1 || signal == SIGFPE);
/* all threads created by the calling thread will have signal blocked */
sigemptyset(&set);
sigaddset(&set, signal);
@ -55,7 +55,7 @@ software_interrupt_unmask_signal(int signal)
sigset_t set;
int return_code;
assert(signal == SIGALRM || signal == SIGUSR1);
assert(signal == SIGALRM || signal == SIGUSR1 || signal == SIGFPE);
/* all threads created by the calling thread will have signal unblocked */
sigemptyset(&set);
sigaddset(&set, signal);

@ -10,6 +10,7 @@ extern _Atomic volatile sig_atomic_t *software_interrupt_counts_deferred_sigalrm
extern _Atomic volatile sig_atomic_t *software_interrupt_counts_deferred_sigalrm_replay;
extern _Atomic volatile sig_atomic_t *software_interrupt_counts_sigalrm_kernel;
extern _Atomic volatile sig_atomic_t *software_interrupt_counts_sigalrm_thread;
extern _Atomic volatile sig_atomic_t *software_interrupt_counts_sigfpe;
extern _Atomic volatile sig_atomic_t *software_interrupt_counts_sigusr;
static inline void
@ -20,6 +21,7 @@ software_interrupt_counts_alloc()
software_interrupt_counts_deferred_sigalrm_replay = calloc(runtime_worker_threads_count, sizeof(sig_atomic_t));
software_interrupt_counts_sigalrm_kernel = calloc(runtime_worker_threads_count, sizeof(sig_atomic_t));
software_interrupt_counts_sigalrm_thread = calloc(runtime_worker_threads_count, sizeof(sig_atomic_t));
software_interrupt_counts_sigfpe = calloc(runtime_worker_threads_count, sizeof(sig_atomic_t));
software_interrupt_counts_sigusr = calloc(runtime_worker_threads_count, sizeof(sig_atomic_t));
#endif
}
@ -29,8 +31,10 @@ software_interrupt_counts_free()
{
#ifdef LOG_SOFTWARE_INTERRUPT_COUNTS
free((void *)software_interrupt_counts_deferred_sigalrm_max);
free((void *)software_interrupt_counts_deferred_sigalrm_replay);
free((void *)software_interrupt_counts_sigalrm_kernel);
free((void *)software_interrupt_counts_sigalrm_thread);
free((void *)software_interrupt_counts_sigfpe);
free((void *)software_interrupt_counts_sigusr);
#endif
}
@ -69,6 +73,14 @@ software_interrupt_counts_sigalrm_thread_increment()
#endif
}
static inline void
software_interrupt_counts_sigfpe_increment()
{
#ifdef LOG_SOFTWARE_INTERRUPT_COUNTS
atomic_fetch_add(&software_interrupt_counts_sigfpe[worker_thread_idx], 1);
#endif
}
static inline void
software_interrupt_counts_sigusr_increment()
{

@ -225,7 +225,7 @@ current_sandbox_start(void)
{
struct sandbox *sandbox = current_sandbox_init();
int rc = setjmp(sandbox->ctxt.start_buf);
int rc = sigsetjmp(sandbox->ctxt.start_buf, 1);
if (rc == 0) {
struct module *current_module = sandbox_get_module(sandbox);
sandbox->return_value = module_entrypoint(current_module);

@ -27,5 +27,5 @@ sledge_abi__current_wasm_module_instance_trap(enum sledge_abi__wasm_trap trapno)
assert(sandbox != NULL);
assert(sandbox->state == SANDBOX_RUNNING_USER || sandbox->state == SANDBOX_RUNNING_SYS);
longjmp(sandbox->ctxt.start_buf, trapno);
siglongjmp(sandbox->ctxt.start_buf, trapno);
}

@ -1066,7 +1066,7 @@ wasi_snapshot_preview1_backing_proc_exit(wasi_context_t *context, __wasi_exitcod
{
struct sandbox *s = current_sandbox_get();
s->return_value = exitcode;
longjmp(s->ctxt.start_buf, WASM_TRAP_EXIT);
siglongjmp(s->ctxt.start_buf, WASM_TRAP_EXIT);
}
/**

@ -149,6 +149,19 @@ software_interrupt_handle_signals(int signal_type, siginfo_t *signal_info, void
break;
}
case SIGFPE: {
software_interrupt_counts_sigfpe_increment();
if (likely(current_sandbox && current_sandbox->state == SANDBOX_RUNNING_USER)) {
atomic_fetch_sub(&handler_depth, 1);
current_sandbox_trap(WASM_TRAP_ILLEGAL_ARITHMETIC_OPERATION);
} else {
// Runtime FPE
panic("Runtime SIGFPE\n");
}
break;
}
default: {
const char *signal_name = strsignal(signal_type);
switch (signal_info->si_code) {
@ -231,9 +244,10 @@ software_interrupt_initialize(void)
sigemptyset(&signal_action.sa_mask);
sigaddset(&signal_action.sa_mask, SIGALRM);
sigaddset(&signal_action.sa_mask, SIGUSR1);
sigaddset(&signal_action.sa_mask, SIGFPE);
const int supported_signals[] = { SIGALRM, SIGUSR1 };
const size_t supported_signals_len = 2;
const int supported_signals[] = { SIGALRM, SIGUSR1, SIGFPE };
const size_t supported_signals_len = 3;
for (int i = 0; i < supported_signals_len; i++) {
int signal = supported_signals[i];

@ -63,6 +63,7 @@ worker_thread_main(void *argument)
if (runtime_preemption_enabled) {
software_interrupt_unmask_signal(SIGALRM);
software_interrupt_unmask_signal(SIGUSR1);
software_interrupt_unmask_signal(SIGFPE);
}
scheduler_idle_loop();

@ -18,7 +18,7 @@ ${SLEDGE_BINARY_DIR}/sledgert:
sledgert: ${SLEDGE_BINARY_DIR}/sledgert
${SLEDGE_BINARY_DIR}/trap_divzero.wasm.so:
make -C ../../../applications trap_divzero.install
make -C ../../applications trap_divzero.install
.PHONY: trap_divzero
trap_divzero: ${SLEDGE_BINARY_DIR}/trap_divzero.wasm.so
@ -40,6 +40,9 @@ client-ok:
client-trap:
echo "0" | http :10000
client-trap2:
echo "-1" | http :10000
test:
echo "4" | http :10000
echo "0" | http :10000

Loading…
Cancel
Save