diff --git a/src/debug.c b/src/debug.c index 0026594d..a3190f63 100644 --- a/src/debug.c +++ b/src/debug.c @@ -266,6 +266,8 @@ void debugCommand(client *c) { blen++; addReplyStatus(c, "segfault -- Crash the server with sigsegv."); blen++; addReplyStatus(c, + "panic -- Crash the server simulating a panic."); + blen++; addReplyStatus(c, "restart -- Graceful restart: save config, db, restart."); blen++; addReplyStatus(c, "crash-and-recovery -- Hard crash and restart after delay."); @@ -300,6 +302,8 @@ void debugCommand(client *c) { setDeferredMultiBulkLength(c,blenp,blen); } else if (!strcasecmp(c->argv[1]->ptr,"segfault")) { *((char*)-1) = 'x'; + } else if (!strcasecmp(c->argv[1]->ptr,"panic")) { + serverPanic("DEBUG PANIC called at Unix time %ld", time(NULL)); } else if (!strcasecmp(c->argv[1]->ptr,"restart") || !strcasecmp(c->argv[1]->ptr,"crash-and-recover")) { @@ -615,11 +619,17 @@ void _serverAssertWithInfo(const client *c, const robj *o, const char *estr, con _serverAssert(estr,file,line); } -void _serverPanic(const char *msg, const char *file, int line) { +void _serverPanic(const char *file, int line, const char *msg, ...) { + va_list ap; + va_start(ap,msg); + char fmtmsg[256]; + vsnprintf(fmtmsg,sizeof(fmtmsg),msg,ap); + va_end(ap); + bugReportStart(); serverLog(LL_WARNING,"------------------------------------------------"); serverLog(LL_WARNING,"!!! Software Failure. Press left mouse button to continue"); - serverLog(LL_WARNING,"Guru Meditation: %s #%s:%d",msg,file,line); + serverLog(LL_WARNING,"Guru Meditation: %s #%s:%d",fmtmsg,file,line); #ifdef HAVE_BACKTRACE serverLog(LL_WARNING,"(forcing SIGSEGV in order to print the stack trace)"); #endif diff --git a/src/server.h b/src/server.h index 96bbb9cc..30d8be84 100644 --- a/src/server.h +++ b/src/server.h @@ -435,7 +435,7 @@ typedef long long mstime_t; /* millisecond time type. */ /* We can print the stacktrace, so our assert is defined this way: */ #define serverAssertWithInfo(_c,_o,_e) ((_e)?(void)0 : (_serverAssertWithInfo(_c,_o,#_e,__FILE__,__LINE__),_exit(1))) #define serverAssert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),_exit(1))) -#define serverPanic(_e) _serverPanic(#_e,__FILE__,__LINE__),_exit(1) +#define serverPanic(...) _serverPanic(__FILE__,__LINE__,__VA_ARGS__),_exit(1) /*----------------------------------------------------------------------------- * Data types @@ -1960,7 +1960,7 @@ void *realloc(void *ptr, size_t size) __attribute__ ((deprecated)); /* Debugging stuff */ void _serverAssertWithInfo(const client *c, const robj *o, const char *estr, const char *file, int line); void _serverAssert(const char *estr, const char *file, int line); -void _serverPanic(const char *msg, const char *file, int line); +void _serverPanic(const char *file, int line, const char *msg, ...); void bugReportStart(void); void serverLogObjectDebugInfo(const robj *o); void sigsegvHandler(int sig, siginfo_t *info, void *secret);