Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: enable V8's WASM trap handlers #27246

Merged
merged 1 commit into from
May 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/inspector_agent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ std::vector<std::string> Split(const std::string& string,
}

#ifdef __POSIX__
static void StartIoThreadWakeup(int signo) {
static void StartIoThreadWakeup(int signo, siginfo_t* info, void* ucontext) {
uv_sem_post(&start_io_thread_semaphore);
}

Expand Down
58 changes: 55 additions & 3 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@
#include "node_report.h"
#endif

#if defined(__APPLE__) || defined(__linux__)
#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
#include <atomic>
#include "v8-wasm-trap-handler-posix.h"
#endif // NODE_USE_V8_WASM_TRAP_HANDLER

// ========== global C headers ==========

#include <fcntl.h> // _O_RDWR
Expand Down Expand Up @@ -177,7 +188,8 @@ void WaitForInspectorDisconnect(Environment* env) {
#endif
}

void SignalExit(int signo) {
#ifdef __POSIX__
void SignalExit(int signo, siginfo_t* info, void* ucontext) {
uv_tty_reset_mode();
#ifdef __FreeBSD__
// FreeBSD has a nasty bug, see RegisterSignalHandler for details
Expand All @@ -188,6 +200,7 @@ void SignalExit(int signo) {
#endif
raise(signo);
}
#endif // __POSIX__

MaybeLocal<Value> ExecuteBootstrapper(Environment* env,
const char* id,
Expand Down Expand Up @@ -434,14 +447,39 @@ void LoadEnvironment(Environment* env) {
USE(StartMainThreadExecution(env));
}

#if NODE_USE_V8_WASM_TRAP_HANDLER
static std::atomic<void (*)(int signo, siginfo_t* info, void* ucontext)>
previous_sigsegv_action;

void TrapWebAssemblyOrContinue(int signo, siginfo_t* info, void* ucontext) {
if (!v8::TryHandleWebAssemblyTrapPosix(signo, info, ucontext)) {
auto prev = previous_sigsegv_action.load();
devsnek marked this conversation as resolved.
Show resolved Hide resolved
if (prev != nullptr) {
prev(signo, info, ucontext);
} else {
uv_tty_reset_mode();
raise(signo);
}
}
}
#endif // NODE_USE_V8_WASM_TRAP_HANDLER

#ifdef __POSIX__
void RegisterSignalHandler(int signal,
void (*handler)(int signal),
void (*handler)(int signal,
siginfo_t* info,
void* ucontext),
devsnek marked this conversation as resolved.
Show resolved Hide resolved
bool reset_handler) {
#if NODE_USE_V8_WASM_TRAP_HANDLER
if (signal == SIGSEGV) {
CHECK(previous_sigsegv_action.is_lock_free());
previous_sigsegv_action.store(handler);
return;
}
devsnek marked this conversation as resolved.
Show resolved Hide resolved
#endif // NODE_USE_V8_WASM_TRAP_HANDLER
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler;
sa.sa_sigaction = handler;
#ifndef __FreeBSD__
// FreeBSD has a nasty bug with SA_RESETHAND reseting the SA_SIGINFO, that is
// in turn set for a libthr wrapper. This leads to a crash.
Expand Down Expand Up @@ -499,6 +537,20 @@ inline void PlatformInit() {
RegisterSignalHandler(SIGINT, SignalExit, true);
RegisterSignalHandler(SIGTERM, SignalExit, true);

#if NODE_USE_V8_WASM_TRAP_HANDLER
// Tell V8 to disable emitting WebAssembly
// memory bounds checks. This means that we have
// to catch the SIGSEGV in TrapWebAssemblyOrContinue
// and pass the signal context to V8.
{
struct sigaction sa;
devsnek marked this conversation as resolved.
Show resolved Hide resolved
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = TrapWebAssemblyOrContinue;
CHECK_EQ(sigaction(SIGSEGV, &sa, nullptr), 0);
}
V8::EnableWebAssemblyTrapHandler(false);
#endif // NODE_USE_V8_WASM_TRAP_HANDLER

// Raise the open file descriptor limit.
struct rlimit lim;
if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max) {
Expand Down
15 changes: 15 additions & 0 deletions src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@

#include <memory>

#ifdef __POSIX__
#include <signal.h>
#endif // __POSIX__

#define NODE_MAKE_VERSION(major, minor, patch) \
((major) * 0x1000 + (minor) * 0x100 + (patch))

Expand Down Expand Up @@ -816,6 +820,17 @@ class NODE_EXTERN AsyncResource {
async_context async_context_;
};

#ifdef __POSIX__
// Register a signal handler without interrupting
// any handlers that node itself needs.
NODE_EXTERN
void RegisterSignalHandler(int signal,
void (*handler)(int signal,
siginfo_t* info,
void* ucontext),
bool reset_handler = false);
#endif // __POSIX__

} // namespace node

#endif // SRC_NODE_H_
5 changes: 1 addition & 4 deletions src/node_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,8 @@ void PrintCaughtException(v8::Isolate* isolate,
const v8::TryCatch& try_catch);

void WaitForInspectorDisconnect(Environment* env);
void SignalExit(int signo);
#ifdef __POSIX__
void RegisterSignalHandler(int signal,
void (*handler)(int signal),
bool reset_handler = false);
void SignalExit(int signal, siginfo_t* info, void* ucontext);
#endif

std::string GetHumanReadableProcessName();
Expand Down
5 changes: 3 additions & 2 deletions src/node_watchdog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,9 @@ void* SigintWatchdogHelper::RunSigintWatchdog(void* arg) {
return nullptr;
}


void SigintWatchdogHelper::HandleSignal(int signum) {
void SigintWatchdogHelper::HandleSignal(int signum,
siginfo_t* info,
void* ucontext) {
uv_sem_post(&instance.sem_);
}

Expand Down
2 changes: 1 addition & 1 deletion src/node_watchdog.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class SigintWatchdogHelper {
bool stopping_;

static void* RunSigintWatchdog(void* arg);
static void HandleSignal(int signum);
static void HandleSignal(int signum, siginfo_t* info, void* ucontext);
#else
bool watchdog_disabled_;
static BOOL WINAPI WinCtrlCHandlerRoutine(DWORD dwCtrlType);
Expand Down