70
70
#include " node_report.h"
71
71
#endif
72
72
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
+
73
84
// ========== global C headers ==========
74
85
75
86
#include < fcntl.h> // _O_RDWR
@@ -177,7 +188,8 @@ void WaitForInspectorDisconnect(Environment* env) {
177
188
#endif
178
189
}
179
190
180
- void SignalExit (int signo) {
191
+ #ifdef __POSIX__
192
+ void SignalExit (int signo, siginfo_t * info, void * ucontext) {
181
193
uv_tty_reset_mode ();
182
194
#ifdef __FreeBSD__
183
195
// FreeBSD has a nasty bug, see RegisterSignalHandler for details
@@ -188,6 +200,7 @@ void SignalExit(int signo) {
188
200
#endif
189
201
raise (signo);
190
202
}
203
+ #endif // __POSIX__
191
204
192
205
MaybeLocal<Value> ExecuteBootstrapper (Environment* env,
193
206
const char * id,
@@ -434,14 +447,39 @@ void LoadEnvironment(Environment* env) {
434
447
USE (StartMainThreadExecution (env));
435
448
}
436
449
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
437
466
438
467
#ifdef __POSIX__
439
468
void RegisterSignalHandler (int signal,
440
- void (*handler)(int signal),
469
+ void (*handler)(int signal,
470
+ siginfo_t * info,
471
+ void * ucontext),
441
472
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
442
480
struct sigaction sa;
443
481
memset (&sa, 0 , sizeof (sa));
444
- sa.sa_handler = handler;
482
+ sa.sa_sigaction = handler;
445
483
#ifndef __FreeBSD__
446
484
// FreeBSD has a nasty bug with SA_RESETHAND reseting the SA_SIGINFO, that is
447
485
// in turn set for a libthr wrapper. This leads to a crash.
@@ -499,6 +537,20 @@ inline void PlatformInit() {
499
537
RegisterSignalHandler (SIGINT, SignalExit, true );
500
538
RegisterSignalHandler (SIGTERM, SignalExit, true );
501
539
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
+
502
554
// Raise the open file descriptor limit.
503
555
struct rlimit lim;
504
556
if (getrlimit (RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max ) {
0 commit comments