diff --git a/src/debug.c b/src/debug.c index b937cd3b08b..3d20cddd890 100644 --- a/src/debug.c +++ b/src/debug.c @@ -337,15 +337,20 @@ void debugCommand(redisClient *c) { } void _redisAssert(char *estr, char *file, int line) { + bugReportStart(); redisLog(REDIS_WARNING,"=== ASSERTION FAILED ==="); redisLog(REDIS_WARNING,"==> %s:%d '%s' is not true",file,line,estr); #ifdef HAVE_BACKTRACE - redisLog(REDIS_WARNING,"(forcing SIGSEGV in order to print the stack trace)"); + server.assert_failed = estr; + server.assert_file = file; + server.assert_line = line; + redisLog(REDIS_WARNING,"(forcing SIGSEGV to print the bug report.)"); *((char*)-1) = 'x'; #endif } void _redisPanic(char *msg, char *file, int line) { + bugReportStart(); redisLog(REDIS_WARNING,"!!! Software Failure. Press left mouse button to continue"); redisLog(REDIS_WARNING,"Guru Meditation: %s #%s:%d",msg,file,line); #ifdef HAVE_BACKTRACE diff --git a/src/redis.c b/src/redis.c index 95eb57bafaf..903354e3558 100644 --- a/src/redis.c +++ b/src/redis.c @@ -886,6 +886,12 @@ void initServerConfig() { /* Slow log */ server.slowlog_log_slower_than = REDIS_SLOWLOG_LOG_SLOWER_THAN; server.slowlog_max_len = REDIS_SLOWLOG_MAX_LEN; + + /* Assert */ + server.assert_failed = ""; + server.assert_file = ""; + server.assert_line = 0; + server.bug_report_start = 0; } void initServer() { @@ -1703,32 +1709,56 @@ static void *getMcontextEip(ucontext_t *uc) { #endif } +void bugReportStart(void) { + if (server.bug_report_start == 0) { + redisLog(REDIS_WARNING, + "=== REDIS BUG REPORT START: Cut & paste starting from here ==="); + server.bug_report_start = 1; + } +} + static void sigsegvHandler(int sig, siginfo_t *info, void *secret) { void *trace[100]; char **messages = NULL; int i, trace_size = 0; ucontext_t *uc = (ucontext_t*) secret; - sds infostring; + sds infostring, clients; struct sigaction act; REDIS_NOTUSED(info); + bugReportStart(); redisLog(REDIS_WARNING, - "======= Ooops! Redis %s got signal: -%d- =======", REDIS_VERSION, sig); - infostring = genRedisInfoString(); - redisLog(REDIS_WARNING, "%s",infostring); - /* It's not safe to sdsfree() the returned string under memory - * corruption conditions. Let it leak as we are going to abort */ + " Redis %s crashed by signal: %d", REDIS_VERSION, sig); + redisLog(REDIS_WARNING, + " Failed assertion: %s (%s:%d)", server.assert_failed, + server.assert_file, server.assert_line); + /* Generate the stack trace */ trace_size = backtrace(trace, 100); + /* overwrite sigaction with caller's address */ if (getMcontextEip(uc) != NULL) { trace[1] = getMcontextEip(uc); } messages = backtrace_symbols(trace, trace_size); - + redisLog(REDIS_WARNING, "--- STACK TRACE"); for (i=1; i