From 4d154a37e0636a78c12e8561a41d19ace3ccd0c5 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Thu, 28 Sep 2023 13:04:55 -0500 Subject: [PATCH] added: better handling for bad math exceptions in debug env --- interpreter/include/vm.h | 1 + interpreter/src/vm/vm.c | 36 +++++++++++++++++++++++++++++++++- interpreter/src/vm/vm_instrs.h | 19 ++++++++++++++---- interpreter/src/wasm/engine.c | 2 +- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/interpreter/include/vm.h b/interpreter/include/vm.h index 85a75789..77220270 100644 --- a/interpreter/include/vm.h +++ b/interpreter/include/vm.h @@ -119,6 +119,7 @@ struct ovm_engine_t { ovm_engine_t *ovm_engine_new(ovm_store_t *store); void ovm_engine_delete(ovm_engine_t *engine); +void ovm_engine_enable_debug(ovm_engine_t *engine, debug_state_t *debug); bool ovm_engine_memory_ensure_capacity(ovm_engine_t *engine, i64 minimum_size); void ovm_engine_memory_copy(ovm_engine_t *engine, i64 target, void *data, i64 size); diff --git a/interpreter/src/vm/vm.c b/interpreter/src/vm/vm.c index ecf4f095..04c2d00b 100644 --- a/interpreter/src/vm/vm.c +++ b/interpreter/src/vm/vm.c @@ -3,6 +3,7 @@ #include "vm.h" #include +#include #include #include // REMOVE THIS!!! only needed for sqrt #include @@ -172,6 +173,29 @@ void ovm_engine_delete(ovm_engine_t *engine) { bh_free(store->heap_allocator, engine); } +static i32 hit_signaled_exception = 0; +static void signal_handler(int signo, siginfo_t *info, void *context) { + hit_signaled_exception = 1; +} + +void ovm_engine_enable_debug(ovm_engine_t *engine, debug_state_t *debug) { + engine->debug = debug; + + struct sigaction sa; + sa.sa_sigaction = signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART | SA_SIGINFO; + + sigaction(SIGQUIT, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGHUP, &sa, NULL); + + // sigaction(SIGSEGV, &sa, NULL); + // sigaction(SIGFPE, &sa, NULL); + // sigaction(SIGINT, &sa, NULL); Don't overload Ctrl+C +} + bool ovm_engine_memory_ensure_capacity(ovm_engine_t *engine, i64 minimum_size) { if (engine->memory_size >= minimum_size) return true; @@ -413,6 +437,12 @@ static void __ovm_trigger_exception(ovm_state_t *state) { static void __ovm_debug_hook(ovm_engine_t *engine, ovm_state_t *state) { if (!state->debug) return; + if (hit_signaled_exception) { + __ovm_trigger_exception(state); + hit_signaled_exception = 0; + return; + } + if (state->debug->run_count == 0) { state->debug->state = debug_state_pausing; @@ -466,12 +496,14 @@ static void __ovm_debug_hook(ovm_engine_t *engine, ovm_state_t *state) { #define OVMI_DISPATCH_NAME ovmi_dispatch #define OVMI_DEBUG_HOOK ((void)0) #define OVMI_EXCEPTION_HOOK ((void)0) +#define OVMI_DIVIDE_CHECK_HOOK(_) ((void)0) #include "./vm_instrs.h" #define OVMI_FUNC_NAME(n) ovmi_exec_debug_##n #define OVMI_DISPATCH_NAME ovmi_debug_dispatch #define OVMI_DEBUG_HOOK __ovm_debug_hook(state->engine, state) #define OVMI_EXCEPTION_HOOK __ovm_trigger_exception(state) +#define OVMI_DIVIDE_CHECK_HOOK(ctype) if (VAL(instr->b).ctype == 0) __ovm_trigger_exception(state) #include "./vm_instrs.h" ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t *program) { @@ -480,7 +512,9 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t ovm_assert(program); ovmi_instr_exec_t *exec_table = ovmi_dispatch; - if (state->debug) exec_table = ovmi_debug_dispatch; + if (state->debug) { + exec_table = ovmi_debug_dispatch; + } ovm_instr_t *code = program->code; u8 *memory = engine->memory; diff --git a/interpreter/src/vm/vm_instrs.h b/interpreter/src/vm/vm_instrs.h index a9430f00..312b6291 100644 --- a/interpreter/src/vm/vm_instrs.h +++ b/interpreter/src/vm/vm_instrs.h @@ -82,10 +82,6 @@ OVMI_INSTR_EXEC(nop) { OVM_OP_EXEC(add, +) OVM_OP_EXEC(sub, -) OVM_OP_EXEC(mul, *) -OVM_OP_EXEC(div_s, /) -OVM_OP_UNSIGNED_EXEC(div, /) -OVM_OP_INTEGER_UNSIGNED_EXEC(rem, %) -OVM_OP_INTEGER_EXEC(rem_s, %) OVM_OP_INTEGER_UNSIGNED_EXEC(and, &) OVM_OP_INTEGER_UNSIGNED_EXEC(or, |) OVM_OP_INTEGER_UNSIGNED_EXEC(xor, ^) @@ -95,6 +91,20 @@ OVM_OP_INTEGER_EXEC(sar, >>) #undef OVM_OP + +#define OVM_OP(t, op, ctype) \ + ovm_assert(VAL(instr->a).type == t && VAL(instr->b).type == t); \ + OVMI_DIVIDE_CHECK_HOOK(ctype); \ + VAL(instr->r).ctype = VAL(instr->a).ctype op VAL(instr->b).ctype; \ + VAL(instr->r).type = t; + +OVM_OP_EXEC(div_s, /) +OVM_OP_UNSIGNED_EXEC(div, /) +OVM_OP_INTEGER_UNSIGNED_EXEC(rem, %) +OVM_OP_INTEGER_EXEC(rem_s, %) + +#undef OVM_OP + #define OVM_OP(t, func, ctype) \ ovm_assert(VAL(instr->a).type == t && VAL(instr->b).type == t); \ VAL(instr->r).ctype = func( VAL(instr->a).ctype, VAL(instr->b).ctype ); \ @@ -641,4 +651,5 @@ static ovmi_instr_exec_t OVMI_DISPATCH_NAME[] = { #undef OVMI_DISPATCH_NAME #undef OVMI_DEBUG_HOOK #undef OVMI_EXCEPTION_HOOK +#undef OVMI_DIVIDE_CHECK_HOOK diff --git a/interpreter/src/wasm/engine.c b/interpreter/src/wasm/engine.c index 666779a7..ef172c62 100644 --- a/interpreter/src/wasm/engine.c +++ b/interpreter/src/wasm/engine.c @@ -20,7 +20,7 @@ wasm_engine_t *wasm_engine_new_with_config(wasm_config_t *config) { if (config && config->debug_enabled) { // This should maybe be moved elsewhere? debug_state_t *debug = bh_alloc_item(store->heap_allocator, debug_state_t); - engine->engine->debug = debug; + ovm_engine_enable_debug(engine->engine, debug); debug_host_init(engine->engine->debug, engine->engine); debug->listen_path = config->listen_path; -- 2.25.1