From: Salvatore Sanfilippo Date: Thu, 5 Apr 2012 08:52:40 +0000 (-0700) Subject: Merge pull request #431 from anydot/f-signal X-Git-Url: https://git.saurik.com/redis.git/commitdiff_plain/0d5f4ba7cde2efa859a5ea04d59079b5909d537a?hp=-c Merge pull request #431 from anydot/f-signal allocate alternate signal stack, change of sigaction flags for sigterm --- 0d5f4ba7cde2efa859a5ea04d59079b5909d537a diff --combined src/redis.c index a387b295,b625c02e..bb97c8d5 --- a/src/redis.c +++ b/src/redis.c @@@ -48,7 -48,6 +48,7 @@@ #include #include #include +#include /* 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}, @@@ -254,6 -256,7 +257,6 @@@ 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); @@@ -267,12 -270,7 +270,12 @@@ 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" @@@ -1762,7 -1756,6 +1765,7 @@@ 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;