]> git.saurik.com Git - redis.git/commitdiff
initial backtrace dumping on sigsegv/sigbus + debug command
authorantirez <antirez@gmail.com>
Thu, 4 Jun 2009 14:45:57 +0000 (16:45 +0200)
committerantirez <antirez@gmail.com>
Thu, 4 Jun 2009 14:45:57 +0000 (16:45 +0200)
Makefile
redis.c

index 00c0f226c69c33f08487307712b36659b626b314..1d4b4e7419a09dac9e27c8e24b547efa4a1a3a15 100644 (file)
--- 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 b925b551b826d0ae3c8334d08fb0f79ad09bef2c..3a9cfc60e3ff6fdd052666c8ad3ce86140a5d957 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -49,6 +49,7 @@
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <limits.h>
+#include <execinfo.h>
 
 #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__