From 7f957c925bb2b9dd8b89b1017b24b0d5f852cd7f Mon Sep 17 00:00:00 2001 From: antirez Date: Thu, 4 Jun 2009 16:45:57 +0200 Subject: [PATCH] initial backtrace dumping on sigsegv/sigbus + debug command --- Makefile | 2 +- redis.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 00c0f226..1d4b4e74 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # This file is released under the BSD license, see the COPYING file DEBUG?= -g -CFLAGS?= -std=c99 -pedantic -O2 -Wall -W -DSDS_ABORT_ON_OOM +CFLAGS?= -std=c99 -pedantic -O -Wall -W -DSDS_ABORT_ON_OOM CCOPT= $(CFLAGS) OBJ = adlist.o ae.o anet.o dict.o redis.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o diff --git a/redis.c b/redis.c index b925b551..3a9cfc60 100644 --- a/redis.c +++ b/redis.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "ae.h" /* Event driven programming library */ #include "sds.h" /* Dynamic safe strings */ @@ -314,6 +315,7 @@ static time_t getExpire(redisDb *db, robj *key); static int setExpire(redisDb *db, robj *key, time_t when); static void updateSalvesWaitingBgsave(int bgsaveerr); static void freeMemoryIfNeeded(void); +static void onSigsegv(int sig); static void authCommand(redisClient *c); static void pingCommand(redisClient *c); @@ -371,6 +373,7 @@ static void expireCommand(redisClient *c); static void getSetCommand(redisClient *c); static void ttlCommand(redisClient *c); static void slaveofCommand(redisClient *c); +static void debugCommand(redisClient *c); /*================================= Globals ================================= */ @@ -434,6 +437,7 @@ static struct redisCommand cmdTable[] = { {"monitor",monitorCommand,1,REDIS_CMD_INLINE}, {"ttl",ttlCommand,2,REDIS_CMD_INLINE}, {"slaveof",slaveofCommand,3,REDIS_CMD_INLINE}, + {"debug",debugCommand,-2,REDIS_CMD_INLINE}, {NULL,NULL,0,0} }; @@ -890,6 +894,8 @@ static void initServer() { signal(SIGHUP, SIG_IGN); signal(SIGPIPE, SIG_IGN); + signal(SIGSEGV, onSigsegv); + signal(SIGBUS, onSigsegv); server.clients = listCreate(); server.slaves = listCreate(); @@ -4048,6 +4054,28 @@ static void freeMemoryIfNeeded(void) { } } +/* ================================= Debugging ============================== */ + +static void debugCommand(redisClient *c) { + if (!strcasecmp(c->argv[1]->ptr,"segfault")) { + *((char*)-1) = 'x'; + } else { + addReplySds(c,sdsnew("-ERR Syntax error, try DEBUG SEGFAULT\r\n")); + } +} + +static void onSigsegv(int sig) { + void *trace[25]; + int n = backtrace(trace, 25); + char **symbols = backtrace_symbols(trace, n); + + redisLog(REDIS_WARNING,"Got %s!!! Redis crashed, backtrace:", + sig == SIGSEGV ? "SIGSEGV" : "SIGBUS"); + for (int i = 0; i < n; i++) + redisLog(REDIS_WARNING,symbols[i]); + exit(1); +} + /* =================================== Main! ================================ */ #ifdef __linux__ -- 2.45.2