]> git.saurik.com Git - redis.git/commitdiff
Merge pull request #431 from anydot/f-signal
authorSalvatore Sanfilippo <antirez@gmail.com>
Thu, 5 Apr 2012 08:52:40 +0000 (01:52 -0700)
committerSalvatore Sanfilippo <antirez@gmail.com>
Thu, 5 Apr 2012 08:52:40 +0000 (01:52 -0700)
allocate alternate signal stack, change of sigaction flags for sigterm

1  2 
src/redis.c

diff --combined src/redis.c
index a387b295693b2209c6e50a99fa2ae0226b8dbbdd,b625c02e09831572abe432153bb78069c4aab790..bb97c8d5939c6dad1690459240ba93864a7de9fe
@@@ -48,7 -48,6 +48,7 @@@
  #include <float.h>
  #include <math.h>
  #include <sys/resource.h>
 +#include <sys/utsname.h>
  
  /* Our shared "common" objects */
  
@@@ -62,6 -61,9 +62,9 @@@ double R_Zero, R_PosInf, R_NegInf, R_Na
  
  /*================================= Globals ================================= */
  
+ /* Alternate stack for SIGSEGV/etc handlers */
+ char altstack[SIGSTKSZ];
  /* Global vars */
  struct redisServer server; /* server global state */
  struct redisCommand *commandTable;
@@@ -223,7 -225,7 +226,7 @@@ struct redisCommand redisCommandTable[
      {"ttl",ttlCommand,2,"r",0,NULL,1,1,1,0,0},
      {"pttl",pttlCommand,2,"r",0,NULL,1,1,1,0,0},
      {"persist",persistCommand,2,"w",0,NULL,1,1,1,0,0},
 -    {"slaveof",slaveofCommand,3,"aws",0,NULL,0,0,0,0,0},
 +    {"slaveof",slaveofCommand,3,"as",0,NULL,0,0,0,0,0},
      {"debug",debugCommand,-2,"as",0,NULL,0,0,0,0,0},
      {"config",configCommand,-2,"ar",0,NULL,0,0,0,0,0},
      {"subscribe",subscribeCommand,-2,"rps",0,NULL,0,0,0,0,0},
  void redisLogRaw(int level, const char *msg) {
      const int syslogLevelMap[] = { LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING };
      const char *c = ".-*#";
 -    time_t now = time(NULL);
      FILE *fp;
      char buf[64];
      int rawmode = (level & REDIS_LOG_RAW);
      if (rawmode) {
          fprintf(fp,"%s",msg);
      } else {
 -        strftime(buf,sizeof(buf),"%d %b %H:%M:%S",localtime(&now));
 +        int off;
 +        struct timeval tv;
 +
 +        gettimeofday(&tv,NULL);
 +        off = strftime(buf,sizeof(buf),"%d %b %H:%M:%S.",localtime(&tv.tv_sec));
 +        snprintf(buf+off,sizeof(buf)-off,"%03d",(int)tv.tv_usec/1000);
          fprintf(fp,"[%d] %s %c %s\n",(int)getpid(),buf,c[level],msg);
      }
      fflush(fp);
@@@ -1084,7 -1082,7 +1087,7 @@@ void initServerConfig() 
      server.repl_syncio_timeout = REDIS_REPL_SYNCIO_TIMEOUT;
      server.repl_serve_stale_data = 1;
      server.repl_slave_ro = 1;
 -    server.repl_down_since = -1;
 +    server.repl_down_since = time(NULL);
  
      /* Client output buffer limits */
      server.client_obuf_limits[REDIS_CLIENT_LIMIT_CLASS_NORMAL].hard_limit_bytes = 0;
@@@ -1740,16 -1738,12 +1743,16 @@@ sds genRedisInfoString(char *section) 
  
      /* Server */
      if (allsections || defsections || !strcasecmp(section,"server")) {
 +        struct utsname name;
 +
          if (sections++) info = sdscat(info,"\r\n");
 +        uname(&name);
          info = sdscatprintf(info,
              "# Server\r\n"
              "redis_version:%s\r\n"
              "redis_git_sha1:%s\r\n"
              "redis_git_dirty:%d\r\n"
 +            "os:%s %s %s\r\n"
              "arch_bits:%d\r\n"
              "multiplexing_api:%s\r\n"
              "gcc_version:%d.%d.%d\r\n"
              REDIS_VERSION,
              redisGitSHA1(),
              strtol(redisGitDirty(),NULL,10) > 0,
 +            name.sysname, name.release, name.machine,
              server.arch_bits,
              aeGetApiName(),
  #ifdef __GNUC__
@@@ -2329,15 -2322,24 +2332,24 @@@ static void sigtermHandler(int sig) 
  
  void setupSignalHandlers(void) {
      struct sigaction act;
+     stack_t stack;
+     stack.ss_sp = altstack;
+     stack.ss_flags = 0;
+     stack.ss_size = SIGSTKSZ;
+     sigaltstack(&stack, NULL);
  
      /* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction is used.
       * Otherwise, sa_handler is used. */
      sigemptyset(&act.sa_mask);
-     act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND;
+     act.sa_flags = 0;
      act.sa_handler = sigtermHandler;
      sigaction(SIGTERM, &act, NULL);
  
  #ifdef HAVE_BACKTRACE
+     /* Use alternate stack so we don't clobber stack in case of segv, or when we run out of stack ..
+      * also resethand & nodefer so we can get interrupted (and killed) if we cause SEGV during SEGV handler */
      sigemptyset(&act.sa_mask);
      act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
      act.sa_sigaction = sigsegvHandler;