From a1c65ceae85232c8d2976d579d251308ebc58bf3 Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Thu, 3 Sep 2020 10:28:18 -0500 Subject: [PATCH] src: enable wasm trap handler on windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/35033 Reviewed-By: Anna Henningsen Reviewed-By: Ben Noordhuis Reviewed-By: David Carlier Reviewed-By: Tobias Nießen Reviewed-By: Shelley Vohr --- src/node.cc | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/node.cc b/src/node.cc index dd2cd0db75dc8a..00cce0fd465541 100644 --- a/src/node.cc +++ b/src/node.cc @@ -69,15 +69,19 @@ #include "large_pages/node_large_page.h" -#if defined(__APPLE__) || defined(__linux__) +#if defined(__APPLE__) || defined(__linux__) || defined(_WIN32) #define NODE_USE_V8_WASM_TRAP_HANDLER 1 #else #define NODE_USE_V8_WASM_TRAP_HANDLER 0 #endif #if NODE_USE_V8_WASM_TRAP_HANDLER +#if defined(_WIN32) +#include "v8-wasm-trap-handler-win.h" +#else #include #include "v8-wasm-trap-handler-posix.h" +#endif #endif // NODE_USE_V8_WASM_TRAP_HANDLER // ========== global C headers ========== @@ -149,6 +153,10 @@ bool v8_initialized = false; // process-relative uptime base in nanoseconds, initialized in node::Start() uint64_t node_start_time; +#if NODE_USE_V8_WASM_TRAP_HANDLER && defined(_WIN32) +PVOID old_vectored_exception_handler; +#endif + // node_v8_platform-inl.h struct V8Platform v8_platform; } // namespace per_process @@ -506,6 +514,14 @@ MaybeLocal StartExecution(Environment* env, StartExecutionCallback cb) { typedef void (*sigaction_cb)(int signo, siginfo_t* info, void* ucontext); #endif #if NODE_USE_V8_WASM_TRAP_HANDLER +#if defined(_WIN32) +static LONG TrapWebAssemblyOrContinue(EXCEPTION_POINTERS* exception) { + if (v8::TryHandleWebAssemblyTrapWindows(exception)) { + return EXCEPTION_CONTINUE_EXECUTION; + } + return EXCEPTION_CONTINUE_SEARCH; +} +#else static std::atomic previous_sigsegv_action; void TrapWebAssemblyOrContinue(int signo, siginfo_t* info, void* ucontext) { @@ -525,6 +541,7 @@ void TrapWebAssemblyOrContinue(int signo, siginfo_t* info, void* ucontext) { } } } +#endif // defined(_WIN32) #endif // NODE_USE_V8_WASM_TRAP_HANDLER #ifdef __POSIX__ @@ -547,7 +564,6 @@ void RegisterSignalHandler(int signal, sigfillset(&sa.sa_mask); CHECK_EQ(sigaction(signal, &sa, nullptr), 0); } - #endif // __POSIX__ #ifdef __POSIX__ @@ -630,6 +646,13 @@ inline void PlatformInit() { RegisterSignalHandler(SIGTERM, SignalExit, true); #if NODE_USE_V8_WASM_TRAP_HANDLER +#if defined(_WIN32) + { + constexpr ULONG first = TRUE; + per_process::old_vectored_exception_handler = + AddVectoredExceptionHandler(first, TrapWebAssemblyOrContinue); + } +#else // Tell V8 to disable emitting WebAssembly // memory bounds checks. This means that we have // to catch the SIGSEGV in TrapWebAssemblyOrContinue @@ -640,6 +663,7 @@ inline void PlatformInit() { sa.sa_sigaction = TrapWebAssemblyOrContinue; CHECK_EQ(sigaction(SIGSEGV, &sa, nullptr), 0); } +#endif // defined(_WIN32) V8::EnableWebAssemblyTrapHandler(false); #endif // NODE_USE_V8_WASM_TRAP_HANDLER @@ -1050,6 +1074,10 @@ void TearDownOncePerProcess() { per_process::v8_initialized = false; V8::Dispose(); +#if NODE_USE_V8_WASM_TRAP_HANDLER && defined(_WIN32) + RemoveVectoredExceptionHandler(per_process::old_vectored_exception_handler); +#endif + // uv_run cannot be called from the time before the beforeExit callback // runs until the program exits unless the event loop has any referenced // handles after beforeExit terminates. This prevents unrefed timers