src: rework early debug signal handling
authorBen Noordhuis <info@bnoordhuis.nl>
Mon, 26 Jan 2015 22:26:33 +0000 (23:26 +0100)
committerBen Noordhuis <info@bnoordhuis.nl>
Wed, 28 Jan 2015 16:44:04 +0000 (17:44 +0100)
Instead of installing an early debug signal handler, simply block the
SIGUSR1 signal at start-up and unblock it when the debugger is ready.

Both approaches are functionally equivalent but blocking the signal
accomplishes it in fewer lines of code.

PR-URL: https://github.com/iojs/io.js/pull/615
Reviewed-By: Sam Roberts <sam@strongloop.com>
src/node.cc

index 6e1d5cc..71dd3a8 100644 (file)
@@ -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<Isolate* volatile*>(&node_isolate));
@@ -3152,10 +3136,11 @@ void DebugProcess(const FunctionCallbackInfo<Value>& 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__
@@ -3324,6 +3309,13 @@ static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
 
 inline void PlatformInit() {
 #ifdef __POSIX__
+  sigset_t sigmask;
+  sigemptyset(&sigmask);
+  sigaddset(&sigmask, SIGUSR1);
+  CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, nullptr));
+  RegisterSignalHandler(SIGPIPE, SIG_IGN);
+  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) {
@@ -3344,10 +3336,6 @@ inline void PlatformInit() {
       }
     } while (min + 1 < max);
   }
-  // Ignore SIGPIPE
-  RegisterSignalHandler(SIGPIPE, SIG_IGN);
-  RegisterSignalHandler(SIGINT, SignalExit, true);
-  RegisterSignalHandler(SIGTERM, SignalExit, true);
 #endif  // __POSIX__
 }
 
@@ -3618,11 +3606,6 @@ int Start(int argc, char** argv) {
   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".