From: antirez Date: Thu, 24 Nov 2011 14:47:26 +0000 (+0100) Subject: better bug report info on crash X-Git-Url: https://git.saurik.com/redis.git/commitdiff_plain/fa5af017d95dfd56b92ebe14064f995b19e4907f better bug report info on crash --- diff --git a/src/debug.c b/src/debug.c index 376e0712..d610d2a9 100644 --- a/src/debug.c +++ b/src/debug.c @@ -297,10 +297,14 @@ 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 } @@ -308,6 +312,7 @@ void _redisAssert(char *estr, char *file, int line) { void _redisAssertPrintClientInfo(redisClient *c) { int j; + bugReportStart(); redisLog(REDIS_WARNING,"=== ASSERTION FAILED CLIENT CONTEXT ==="); redisLog(REDIS_WARNING,"client->flags = %d", c->flags); redisLog(REDIS_WARNING,"client->fd = %d", c->fd); @@ -331,6 +336,7 @@ void _redisAssertPrintClientInfo(redisClient *c) { } void _redisAssertPrintObject(robj *o) { + bugReportStart(); redisLog(REDIS_WARNING,"=== ASSERTION FAILED OBJECT CONTEXT ==="); redisLog(REDIS_WARNING,"Object type: %d", o->type); redisLog(REDIS_WARNING,"Object encoding: %d", o->encoding); @@ -349,6 +355,7 @@ void _redisAssertWithInfo(redisClient *c, robj *o, char *estr, char *file, int l } void _redisPanic(char *msg, char *file, int line) { + bugReportStart(); redisLog(REDIS_WARNING,"------------------------------------------------"); redisLog(REDIS_WARNING,"!!! Software Failure. Press left mouse button to continue"); redisLog(REDIS_WARNING,"Guru Meditation: %s #%s:%d",msg,file,line); diff --git a/src/redis.c b/src/redis.c index eb391f1a..735de9d6 100644 --- a/src/redis.c +++ b/src/redis.c @@ -946,6 +946,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() { @@ -1946,32 +1952,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("all"); - redisLogRaw(REDIS_WARNING, 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