]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common: prevent infinite recursion on SIGSEGV
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Mon, 29 Nov 2010 22:46:08 +0000 (14:46 -0800)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Mon, 29 Nov 2010 23:12:11 +0000 (15:12 -0800)
Install SIGSEGV / SIGABORT handlers with sigaction using SA_RESETHAND.
This will ensure that if the signal handler itself encounters another
fault, the default signal handler (usually dump core) will be what is
used. Also, flush the log before dumping core.

Signed-off-by: Colin McCabe <colinm@hq.newdream.net>
src/config.cc
src/os/FileStore.h

index d877f72816c4da85728c530271303626c774cef1..ad514a6a47357d6d295f2c309754e6816c56cd80 100644 (file)
@@ -212,23 +212,41 @@ void parse_config_option_string(string& s)
   parse_config_options(nargs);
 }
 
+typedef void (*signal_handler_t)(int);
+
+static void install_sighandler(int signum, signal_handler_t handler, int flags)
+{
+  int ret;
+  struct sigaction oldact;
+  struct sigaction act;
+  memset(&act, 0, sizeof(act));
+
+  act.sa_handler = handler;
+  sigemptyset(&act.sa_mask);
+  act.sa_flags = flags;
+
+  ret = sigaction(signum, &act, &oldact);
+  if (ret != 0) {
+    fprintf(stderr, "failed to install signal handler for signal %d\n", signum);
+    exit(1);
+  }
+}
+
 void sighup_handler(int signum)
 {
   _dout_need_open = true;
   logger_reopen_all();
 }
 
-static void (*old_sigsegv_handler)(int) = NULL;
-static void (*old_sigabrt_handler)(int) = NULL;
-
 void sigsegv_handler(int signum)
 {
   *_dout << "*** Caught signal (SEGV) ***" << std::endl;
   BackTrace bt(0);
   bt.print(*_dout);
+  _dout->flush();
 
-  if (old_sigsegv_handler)
-    old_sigsegv_handler(signum);
+  // Use default handler to dump core
+  kill(getpid(), signum);
 }
 
 void sigabrt_handler(int signum)
@@ -236,10 +254,10 @@ void sigabrt_handler(int signum)
   *_dout << "*** Caught signal (ABRT) ***" << std::endl;
   BackTrace bt(0);
   bt.print(*_dout);
+  _dout->flush();
 
-  //*_dout << "i am " << (void*)sigabrt_handler << ", chaining to " << (void*)old_sigabrt_handler << std::endl;
-  if (old_sigabrt_handler)
-    old_sigabrt_handler(signum);
+  // Use default handler to dump core
+  kill(getpid(), signum);
 }
 
 #define _STR(x) #x
@@ -1281,17 +1299,9 @@ void parse_config_options(std::vector<const char*>& args)
         nargs.push_back(args[i]);
   }
 
-  signal(SIGHUP, sighup_handler);
-  if (!old_sigsegv_handler) {
-    old_sigsegv_handler = signal(SIGSEGV, sigsegv_handler);
-    if (old_sigsegv_handler == sigsegv_handler)
-      old_sigsegv_handler = NULL;
-  }
-  if (!old_sigabrt_handler) {
-    old_sigabrt_handler = signal(SIGABRT, sigabrt_handler);
-    if (old_sigabrt_handler == sigabrt_handler)
-      old_sigabrt_handler = NULL;
-  }
+  install_sighandler(SIGHUP, sighup_handler, SA_RESTART);
+  install_sighandler(SIGSEGV, sigsegv_handler, SA_RESETHAND);
+  install_sighandler(SIGSEGV, sigabrt_handler, SA_RESETHAND);
 
   args = nargs;
 }
index dbedefe326373b698a839a81065de882db294987..3c4e2a26d67b7f6a8d623f828703e60f14efcc99 100644 (file)
@@ -26,8 +26,6 @@
 #include "Fake.h"
 //#include "FakeStoreBDBCollections.h"
 
-#include <signal.h>
-
 #include <map>
 #include <deque>
 using namespace std;