7070#include " node_report.h"
7171#endif
7272
73+ #if defined(__APPLE__) || defined(__linux__)
74+ #define NODE_USE_V8_WASM_TRAP_HANDLER 1
75+ #else
76+ #define NODE_USE_V8_WASM_TRAP_HANDLER 0
77+ #endif
78+
79+ #if NODE_USE_V8_WASM_TRAP_HANDLER
80+ #include < atomic>
81+ #include " v8-wasm-trap-handler-posix.h"
82+ #endif // NODE_USE_V8_WASM_TRAP_HANDLER
83+
7384// ========== global C headers ==========
7485
7586#include < fcntl.h> // _O_RDWR
@@ -177,7 +188,8 @@ void WaitForInspectorDisconnect(Environment* env) {
177188#endif
178189}
179190
180- void SignalExit (int signo) {
191+ #ifdef __POSIX__
192+ void SignalExit (int signo, siginfo_t * info, void * ucontext) {
181193 uv_tty_reset_mode ();
182194#ifdef __FreeBSD__
183195 // FreeBSD has a nasty bug, see RegisterSignalHandler for details
@@ -188,6 +200,7 @@ void SignalExit(int signo) {
188200#endif
189201 raise (signo);
190202}
203+ #endif // __POSIX__
191204
192205MaybeLocal<Value> ExecuteBootstrapper (Environment* env,
193206 const char * id,
@@ -434,14 +447,39 @@ void LoadEnvironment(Environment* env) {
434447 USE (StartMainThreadExecution (env));
435448}
436449
450+ #if NODE_USE_V8_WASM_TRAP_HANDLER
451+ static std::atomic<void (*)(int signo, siginfo_t * info, void * ucontext)>
452+ previous_sigsegv_action;
453+
454+ void TrapWebAssemblyOrContinue (int signo, siginfo_t * info, void * ucontext) {
455+ if (!v8::TryHandleWebAssemblyTrapPosix (signo, info, ucontext)) {
456+ auto prev = previous_sigsegv_action.load ();
457+ if (prev != nullptr ) {
458+ prev (signo, info, ucontext);
459+ } else {
460+ uv_tty_reset_mode ();
461+ raise (signo);
462+ }
463+ }
464+ }
465+ #endif // NODE_USE_V8_WASM_TRAP_HANDLER
437466
438467#ifdef __POSIX__
439468void RegisterSignalHandler (int signal,
440- void (*handler)(int signal),
469+ void (*handler)(int signal,
470+ siginfo_t * info,
471+ void * ucontext),
441472 bool reset_handler) {
473+ #if NODE_USE_V8_WASM_TRAP_HANDLER
474+ if (signal == SIGSEGV) {
475+ CHECK (previous_sigsegv_action.is_lock_free ());
476+ previous_sigsegv_action.store (handler);
477+ return ;
478+ }
479+ #endif // NODE_USE_V8_WASM_TRAP_HANDLER
442480 struct sigaction sa;
443481 memset (&sa, 0 , sizeof (sa));
444- sa.sa_handler = handler;
482+ sa.sa_sigaction = handler;
445483#ifndef __FreeBSD__
446484 // FreeBSD has a nasty bug with SA_RESETHAND reseting the SA_SIGINFO, that is
447485 // in turn set for a libthr wrapper. This leads to a crash.
@@ -499,6 +537,20 @@ inline void PlatformInit() {
499537 RegisterSignalHandler (SIGINT, SignalExit, true );
500538 RegisterSignalHandler (SIGTERM, SignalExit, true );
501539
540+ #if NODE_USE_V8_WASM_TRAP_HANDLER
541+ // Tell V8 to disable emitting WebAssembly
542+ // memory bounds checks. This means that we have
543+ // to catch the SIGSEGV in TrapWebAssemblyOrContinue
544+ // and pass the signal context to V8.
545+ {
546+ struct sigaction sa;
547+ memset (&sa, 0 , sizeof (sa));
548+ sa.sa_sigaction = TrapWebAssemblyOrContinue;
549+ CHECK_EQ (sigaction (SIGSEGV, &sa, nullptr ), 0 );
550+ }
551+ V8::EnableWebAssemblyTrapHandler (false );
552+ #endif // NODE_USE_V8_WASM_TRAP_HANDLER
553+
502554 // Raise the open file descriptor limit.
503555 struct rlimit lim;
504556 if (getrlimit (RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max ) {
0 commit comments