diff --git a/src/node.cc b/src/node.cc index b83485c9d39da1..72ddbe178e37b9 100644 --- a/src/node.cc +++ b/src/node.cc @@ -3096,22 +3096,6 @@ static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle) { #ifdef __POSIX__ -static volatile sig_atomic_t caught_early_debug_signal; - - -static void EarlyDebugSignalHandler(int signo) { - caught_early_debug_signal = 1; -} - - -static void InstallEarlyDebugSignalHandler() { - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = EarlyDebugSignalHandler; - sigaction(SIGUSR1, &sa, nullptr); -} - - static void EnableDebugSignalHandler(int signo) { // Call only async signal-safe functions here! v8::Debug::DebugBreak(*static_cast(&node_isolate)); @@ -3152,10 +3136,11 @@ void DebugProcess(const FunctionCallbackInfo& args) { static int RegisterDebugSignalHandler() { // FIXME(bnoordhuis) Should be per-isolate or per-context, not global. RegisterSignalHandler(SIGUSR1, EnableDebugSignalHandler); - // If we caught a SIGUSR1 during the bootstrap process, re-raise it - // now that the debugger infrastructure is in place. - if (caught_early_debug_signal) - raise(SIGUSR1); + // Unblock SIGUSR1. A pending SIGUSR1 signal will now be delivered. + sigset_t sigmask; + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGUSR1); + CHECK_EQ(0, pthread_sigmask(SIG_UNBLOCK, &sigmask, nullptr)); return 0; } #endif // __POSIX__ @@ -3322,6 +3307,54 @@ static void DebugEnd(const FunctionCallbackInfo& args) { } +inline void PlatformInit() { +#ifdef __POSIX__ + sigset_t sigmask; + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGUSR1); + CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, nullptr)); + + // Restore signal dispositions, the parent process may have changed them. + struct sigaction act; + memset(&act, 0, sizeof(act)); + + // The hard-coded upper limit is because NSIG is not very reliable; on Linux, + // it evaluates to 32, 34 or 64, depending on whether RT signals are enabled. + // Counting up to SIGRTMIN doesn't work for the same reason. + for (unsigned nr = 1; nr < 32; nr += 1) { + if (nr == SIGKILL || nr == SIGSTOP) + continue; + act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL; + CHECK_EQ(0, sigaction(nr, &act, nullptr)); + } + + RegisterSignalHandler(SIGINT, SignalExit, true); + RegisterSignalHandler(SIGTERM, SignalExit, true); + + // Raise the open file descriptor limit. + struct rlimit lim; + if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max) { + // Do a binary search for the limit. + rlim_t min = lim.rlim_cur; + rlim_t max = 1 << 20; + // But if there's a defined upper bound, don't search, just set it. + if (lim.rlim_max != RLIM_INFINITY) { + min = lim.rlim_max; + max = lim.rlim_max; + } + do { + lim.rlim_cur = min + (max - min) / 2; + if (setrlimit(RLIMIT_NOFILE, &lim)) { + max = lim.rlim_cur; + } else { + min = lim.rlim_cur; + } + } while (min + 1 < max); + } +#endif // __POSIX__ +} + + void Init(int* argc, const char** argv, int* exec_argc, @@ -3396,35 +3429,6 @@ void Init(int* argc, V8::SetArrayBufferAllocator(&ArrayBufferAllocator::the_singleton); -#ifdef __POSIX__ - // Raise the open file descriptor limit. - { // NOLINT (whitespace/braces) - struct rlimit lim; - if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max) { - // Do a binary search for the limit. - rlim_t min = lim.rlim_cur; - rlim_t max = 1 << 20; - // But if there's a defined upper bound, don't search, just set it. - if (lim.rlim_max != RLIM_INFINITY) { - min = lim.rlim_max; - max = lim.rlim_max; - } - do { - lim.rlim_cur = min + (max - min) / 2; - if (setrlimit(RLIMIT_NOFILE, &lim)) { - max = lim.rlim_cur; - } else { - min = lim.rlim_cur; - } - } while (min + 1 < max); - } - } - // Ignore SIGPIPE - RegisterSignalHandler(SIGPIPE, SIG_IGN); - RegisterSignalHandler(SIGINT, SignalExit, true); - RegisterSignalHandler(SIGTERM, SignalExit, true); -#endif // __POSIX__ - if (!use_debug_agent) { RegisterDebugSignalHandler(); } @@ -3610,16 +3614,13 @@ Environment* CreateEnvironment(Isolate* isolate, int Start(int argc, char** argv) { + PlatformInit(); + const char* replaceInvalid = secure_getenv("NODE_INVALID_UTF8"); if (replaceInvalid == nullptr) WRITE_UTF8_FLAGS |= String::REPLACE_INVALID_UTF8; -#if !defined(_WIN32) - // Try hard not to lose SIGUSR1 signals during the bootstrap process. - InstallEarlyDebugSignalHandler(); -#endif - CHECK_GT(argc, 0); // Hack around with the argv pointer. Used for process.title = "blah".