]> git.saurik.com Git - redis.git/commitdiff
Tcl script, make target, and redis.c changes to build the static symbol table automag...
authorantirez <antirez@gmail.com>
Tue, 10 Nov 2009 18:20:32 +0000 (19:20 +0100)
committerantirez <antirez@gmail.com>
Tue, 10 Nov 2009 18:20:32 +0000 (19:20 +0100)
Makefile
TODO
redis.c
staticsymbols.h [new file with mode: 0644]
utils/build-static-symbols.tcl [new file with mode: 0644]

index 49d0cb3808b923cbaefd603fd7c39943c97feead..9e687d25aea3a4bd30d06843cb73557d8dadb0f9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -60,6 +60,9 @@ clean:
 dep:
        $(CC) -MM *.c
 
+staticsymbols:
+       tclsh utils/build-static-symbols.tcl > staticsymbols.h
+
 test:
        tclsh test-redis.tcl
 
diff --git a/TODO b/TODO
index 1df6be8bfc24c5a217132c9c1c45a90ee853900e..b63a4a43957ca9c564db7d85aa56fcce4b7702b2 100644 (file)
--- a/TODO
+++ b/TODO
@@ -10,7 +10,6 @@ VERSION 1.1 TODO
 * Write docs for the "STORE" operaiton of SORT, and GET "#" option.
 * Append only mode: testing and a command to rebuild the log from scratch.
 * Profiling and optimizations. For instance the commands lookup is probably starting to eat too CPU being a simple list. To implement binary search or an hash table lookup can be a win probably.
-* Expiring algorithm should be adaptive. Use the following algorithm. Start testing REDIS_EXPIRELOOKUPS_PER_CRON in the first iteration, and continue with the same amount of keys until the percentage of expired keys > 25%.
 
 VERSION 1.2 TODO
 
diff --git a/redis.c b/redis.c
index 2d196674f8f237e7041e6e9718dce29ea44f6421..12bd856762d9babcf8a40897dcd6297b66bdb610 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -544,6 +544,7 @@ static struct redisCommand cmdTable[] = {
     {"debug",debugCommand,-2,REDIS_CMD_INLINE},
     {NULL,NULL,0,0}
 };
+
 /*============================ Utility functions ============================ */
 
 /* Glob-style pattern matching. */
@@ -1025,7 +1026,7 @@ static void appendServerSaveParams(time_t seconds, int changes) {
     server.saveparamslen++;
 }
 
-static void ResetServerSaveParams() {
+static void resetServerSaveParams() {
     zfree(server.saveparams);
     server.saveparams = NULL;
     server.saveparamslen = 0;
@@ -1054,7 +1055,7 @@ static void initServerConfig() {
     server.sharingpoolsize = 1024;
     server.maxclients = 0;
     server.maxmemory = 0;
-    ResetServerSaveParams();
+    resetServerSaveParams();
 
     appendServerSaveParams(60*60,1);  /* save after 1 hour and 1 change */
     appendServerSaveParams(300,100);  /* save after 5 minutes and 100 changes */
@@ -5534,150 +5535,91 @@ static void debugCommand(redisClient *c) {
     }
 }
 
-#ifdef HAVE_BACKTRACE
-static struct redisFunctionSym symsTable[] = {
-{"compareStringObjects", (unsigned long)compareStringObjects},
-{"isStringRepresentableAsLong", (unsigned long)isStringRepresentableAsLong},
-{"dictEncObjKeyCompare", (unsigned long)dictEncObjKeyCompare},
-{"dictEncObjHash", (unsigned long)dictEncObjHash},
-{"incrDecrCommand", (unsigned long)incrDecrCommand},
-{"freeStringObject", (unsigned long)freeStringObject},
-{"freeListObject", (unsigned long)freeListObject},
-{"freeSetObject", (unsigned long)freeSetObject},
-{"decrRefCount", (unsigned long)decrRefCount},
-{"createObject", (unsigned long)createObject},
-{"freeClient", (unsigned long)freeClient},
-{"rdbLoad", (unsigned long)rdbLoad},
-{"rdbSaveStringObject", (unsigned long)rdbSaveStringObject},
-{"rdbSaveStringObjectRaw", (unsigned long)rdbSaveStringObjectRaw},
-{"addReply", (unsigned long)addReply},
-{"addReplySds", (unsigned long)addReplySds},
-{"incrRefCount", (unsigned long)incrRefCount},
-{"rdbSaveBackground", (unsigned long)rdbSaveBackground},
-{"createStringObject", (unsigned long)createStringObject},
-{"replicationFeedSlaves", (unsigned long)replicationFeedSlaves},
-{"syncWithMaster", (unsigned long)syncWithMaster},
-{"tryObjectSharing", (unsigned long)tryObjectSharing},
-{"tryObjectEncoding", (unsigned long)tryObjectEncoding},
-{"getDecodedObject", (unsigned long)getDecodedObject},
-{"removeExpire", (unsigned long)removeExpire},
-{"expireIfNeeded", (unsigned long)expireIfNeeded},
-{"deleteIfVolatile", (unsigned long)deleteIfVolatile},
-{"deleteKey", (unsigned long)deleteKey},
-{"getExpire", (unsigned long)getExpire},
-{"setExpire", (unsigned long)setExpire},
-{"updateSlavesWaitingBgsave", (unsigned long)updateSlavesWaitingBgsave},
-{"freeMemoryIfNeeded", (unsigned long)freeMemoryIfNeeded},
-{"authCommand", (unsigned long)authCommand},
-{"pingCommand", (unsigned long)pingCommand},
-{"echoCommand", (unsigned long)echoCommand},
-{"setCommand", (unsigned long)setCommand},
-{"setnxCommand", (unsigned long)setnxCommand},
-{"getCommand", (unsigned long)getCommand},
-{"delCommand", (unsigned long)delCommand},
-{"existsCommand", (unsigned long)existsCommand},
-{"incrCommand", (unsigned long)incrCommand},
-{"decrCommand", (unsigned long)decrCommand},
-{"incrbyCommand", (unsigned long)incrbyCommand},
-{"decrbyCommand", (unsigned long)decrbyCommand},
-{"selectCommand", (unsigned long)selectCommand},
-{"randomkeyCommand", (unsigned long)randomkeyCommand},
-{"keysCommand", (unsigned long)keysCommand},
-{"dbsizeCommand", (unsigned long)dbsizeCommand},
-{"lastsaveCommand", (unsigned long)lastsaveCommand},
-{"saveCommand", (unsigned long)saveCommand},
-{"bgsaveCommand", (unsigned long)bgsaveCommand},
-{"shutdownCommand", (unsigned long)shutdownCommand},
-{"moveCommand", (unsigned long)moveCommand},
-{"renameCommand", (unsigned long)renameCommand},
-{"renamenxCommand", (unsigned long)renamenxCommand},
-{"lpushCommand", (unsigned long)lpushCommand},
-{"rpushCommand", (unsigned long)rpushCommand},
-{"lpopCommand", (unsigned long)lpopCommand},
-{"rpopCommand", (unsigned long)rpopCommand},
-{"llenCommand", (unsigned long)llenCommand},
-{"lindexCommand", (unsigned long)lindexCommand},
-{"lrangeCommand", (unsigned long)lrangeCommand},
-{"ltrimCommand", (unsigned long)ltrimCommand},
-{"typeCommand", (unsigned long)typeCommand},
-{"lsetCommand", (unsigned long)lsetCommand},
-{"saddCommand", (unsigned long)saddCommand},
-{"sremCommand", (unsigned long)sremCommand},
-{"smoveCommand", (unsigned long)smoveCommand},
-{"sismemberCommand", (unsigned long)sismemberCommand},
-{"scardCommand", (unsigned long)scardCommand},
-{"spopCommand", (unsigned long)spopCommand},
-{"srandmemberCommand", (unsigned long)srandmemberCommand},
-{"sinterCommand", (unsigned long)sinterCommand},
-{"sinterstoreCommand", (unsigned long)sinterstoreCommand},
-{"sunionCommand", (unsigned long)sunionCommand},
-{"sunionstoreCommand", (unsigned long)sunionstoreCommand},
-{"sdiffCommand", (unsigned long)sdiffCommand},
-{"sdiffstoreCommand", (unsigned long)sdiffstoreCommand},
-{"syncCommand", (unsigned long)syncCommand},
-{"flushdbCommand", (unsigned long)flushdbCommand},
-{"flushallCommand", (unsigned long)flushallCommand},
-{"sortCommand", (unsigned long)sortCommand},
-{"lremCommand", (unsigned long)lremCommand},
-{"infoCommand", (unsigned long)infoCommand},
-{"mgetCommand", (unsigned long)mgetCommand},
-{"monitorCommand", (unsigned long)monitorCommand},
-{"expireCommand", (unsigned long)expireCommand},
-{"expireatCommand", (unsigned long)expireatCommand},
-{"getsetCommand", (unsigned long)getsetCommand},
-{"ttlCommand", (unsigned long)ttlCommand},
-{"slaveofCommand", (unsigned long)slaveofCommand},
-{"debugCommand", (unsigned long)debugCommand},
-{"processCommand", (unsigned long)processCommand},
-{"setupSigSegvAction", (unsigned long)setupSigSegvAction},
-{"readQueryFromClient", (unsigned long)readQueryFromClient},
-{"rdbRemoveTempFile", (unsigned long)rdbRemoveTempFile},
-{"msetGenericCommand", (unsigned long)msetGenericCommand},
-{"msetCommand", (unsigned long)msetCommand},
-{"msetnxCommand", (unsigned long)msetnxCommand},
-{"zslCreateNode", (unsigned long)zslCreateNode},
-{"zslCreate", (unsigned long)zslCreate},
-{"zslFreeNode",(unsigned long)zslFreeNode},
-{"zslFree",(unsigned long)zslFree},
-{"zslRandomLevel",(unsigned long)zslRandomLevel},
-{"zslInsert",(unsigned long)zslInsert},
-{"zslDelete",(unsigned long)zslDelete},
-{"createZsetObject",(unsigned long)createZsetObject},
-{"zaddCommand",(unsigned long)zaddCommand},
-{"zrangeGenericCommand",(unsigned long)zrangeGenericCommand},
-{"zrangeCommand",(unsigned long)zrangeCommand},
-{"zrevrangeCommand",(unsigned long)zrevrangeCommand},
-{"zremCommand",(unsigned long)zremCommand},
-{"rdbSaveDoubleValue",(unsigned long)rdbSaveDoubleValue},
-{"rdbLoadDoubleValue",(unsigned long)rdbLoadDoubleValue},
-{"feedAppendOnlyFile",(unsigned long)feedAppendOnlyFile},
-{NULL,0}
-};
+/* =================================== Main! ================================ */
 
-/* This function try to convert a pointer into a function name. It's used in
- * oreder to provide a backtrace under segmentation fault that's able to
- * display functions declared as static (otherwise the backtrace is useless). */
-static char *findFuncName(void *pointer, unsigned long *offset){
-    int i, ret = -1;
-    unsigned long off, minoff = 0;
+#ifdef __linux__
+int linuxOvercommitMemoryValue(void) {
+    FILE *fp = fopen("/proc/sys/vm/overcommit_memory","r");
+    char buf[64];
 
-    /* Try to match against the Symbol with the smallest offset */
-    for (i=0; symsTable[i].pointer; i++) {
-        unsigned long lp = (unsigned long) pointer;
+    if (!fp) return -1;
+    if (fgets(buf,64,fp) == NULL) {
+        fclose(fp);
+        return -1;
+    }
+    fclose(fp);
 
-        if (lp != (unsigned long)-1 && lp >= symsTable[i].pointer) {
-            off=lp-symsTable[i].pointer;
-            if (ret < 0 || off < minoff) {
-                minoff=off;
-                ret=i;
-            }
-        }
+    return atoi(buf);
+}
+
+void linuxOvercommitMemoryWarning(void) {
+    if (linuxOvercommitMemoryValue() == 0) {
+        redisLog(REDIS_WARNING,"WARNING overcommit_memory is set to 0! Background save may fail under low condition memory. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.");
+    }
+}
+#endif /* __linux__ */
+
+static void daemonize(void) {
+    int fd;
+    FILE *fp;
+
+    if (fork() != 0) exit(0); /* parent exits */
+    setsid(); /* create a new session */
+
+    /* Every output goes to /dev/null. If Redis is daemonized but
+     * the 'logfile' is set to 'stdout' in the configuration file
+     * it will not log at all. */
+    if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
+        dup2(fd, STDIN_FILENO);
+        dup2(fd, STDOUT_FILENO);
+        dup2(fd, STDERR_FILENO);
+        if (fd > STDERR_FILENO) close(fd);
+    }
+    /* Try to write the pid file */
+    fp = fopen(server.pidfile,"w");
+    if (fp) {
+        fprintf(fp,"%d\n",getpid());
+        fclose(fp);
     }
-    if (ret == -1) return NULL;
-    *offset = minoff;
-    return symsTable[ret].name;
 }
 
+int main(int argc, char **argv) {
+    initServerConfig();
+    if (argc == 2) {
+        resetServerSaveParams();
+        loadServerConfig(argv[1]);
+    } else if (argc > 2) {
+        fprintf(stderr,"Usage: ./redis-server [/path/to/redis.conf]\n");
+        exit(1);
+    } else {
+        redisLog(REDIS_WARNING,"Warning: no config file specified, using the default config. In order to specify a config file use 'redis-server /path/to/redis.conf'");
+    }
+    initServer();
+    if (server.daemonize) daemonize();
+    redisLog(REDIS_NOTICE,"Server started, Redis version " REDIS_VERSION);
+#ifdef __linux__
+    linuxOvercommitMemoryWarning();
+#endif
+    if (server.appendonly) {
+        if (loadAppendOnlyFile(server.appendfilename) == REDIS_OK)
+            redisLog(REDIS_NOTICE,"DB loaded from append only file");
+    } else {
+        if (rdbLoad(server.dbfilename) == REDIS_OK)
+            redisLog(REDIS_NOTICE,"DB loaded from disk");
+    }
+    if (aeCreateFileEvent(server.el, server.fd, AE_READABLE,
+        acceptHandler, NULL, NULL) == AE_ERR) oom("creating file event");
+    redisLog(REDIS_NOTICE,"The server is now ready to accept connections on port %d", server.port);
+    aeMain(server.el);
+    aeDeleteEventLoop(server.el);
+    return 0;
+}
+
+/* ============================= Backtrace support ========================= */
+
+#ifdef HAVE_BACKTRACE
+static char *findFuncName(void *pointer, unsigned long *offset);
+
 static void *getMcontextEip(ucontext_t *uc) {
 #if defined(__FreeBSD__)
     return (void*) uc->uc_mcontext.mc_eip;
@@ -5772,87 +5714,39 @@ static void setupSigSegvAction(void) {
     sigaction (SIGBUS, &act, NULL);
     return;
 }
-#else /* HAVE_BACKTRACE */
-static void setupSigSegvAction(void) {
-}
-#endif /* HAVE_BACKTRACE */
 
-/* =================================== Main! ================================ */
+#include "staticsymbols.h"
+/* This function try to convert a pointer into a function name. It's used in
+ * oreder to provide a backtrace under segmentation fault that's able to
+ * display functions declared as static (otherwise the backtrace is useless). */
+static char *findFuncName(void *pointer, unsigned long *offset){
+    int i, ret = -1;
+    unsigned long off, minoff = 0;
 
-#ifdef __linux__
-int linuxOvercommitMemoryValue(void) {
-    FILE *fp = fopen("/proc/sys/vm/overcommit_memory","r");
-    char buf[64];
+    /* Try to match against the Symbol with the smallest offset */
+    for (i=0; symsTable[i].pointer; i++) {
+        unsigned long lp = (unsigned long) pointer;
 
-    if (!fp) return -1;
-    if (fgets(buf,64,fp) == NULL) {
-        fclose(fp);
-        return -1;
+        if (lp != (unsigned long)-1 && lp >= symsTable[i].pointer) {
+            off=lp-symsTable[i].pointer;
+            if (ret < 0 || off < minoff) {
+                minoff=off;
+                ret=i;
+            }
+        }
     }
-    fclose(fp);
-
-    return atoi(buf);
+    if (ret == -1) return NULL;
+    *offset = minoff;
+    return symsTable[ret].name;
 }
-
-void linuxOvercommitMemoryWarning(void) {
-    if (linuxOvercommitMemoryValue() == 0) {
-        redisLog(REDIS_WARNING,"WARNING overcommit_memory is set to 0! Background save may fail under low condition memory. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.");
-    }
+#else /* HAVE_BACKTRACE */
+static void setupSigSegvAction(void) {
 }
-#endif /* __linux__ */
+#endif /* HAVE_BACKTRACE */
 
-static void daemonize(void) {
-    int fd;
-    FILE *fp;
 
-    if (fork() != 0) exit(0); /* parent exits */
-    setsid(); /* create a new session */
 
-    /* Every output goes to /dev/null. If Redis is daemonized but
-     * the 'logfile' is set to 'stdout' in the configuration file
-     * it will not log at all. */
-    if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
-        dup2(fd, STDIN_FILENO);
-        dup2(fd, STDOUT_FILENO);
-        dup2(fd, STDERR_FILENO);
-        if (fd > STDERR_FILENO) close(fd);
-    }
-    /* Try to write the pid file */
-    fp = fopen(server.pidfile,"w");
-    if (fp) {
-        fprintf(fp,"%d\n",getpid());
-        fclose(fp);
-    }
-}
+/* The End */
+
+
 
-int main(int argc, char **argv) {
-    initServerConfig();
-    if (argc == 2) {
-        ResetServerSaveParams();
-        loadServerConfig(argv[1]);
-    } else if (argc > 2) {
-        fprintf(stderr,"Usage: ./redis-server [/path/to/redis.conf]\n");
-        exit(1);
-    } else {
-        redisLog(REDIS_WARNING,"Warning: no config file specified, using the default config. In order to specify a config file use 'redis-server /path/to/redis.conf'");
-    }
-    initServer();
-    if (server.daemonize) daemonize();
-    redisLog(REDIS_NOTICE,"Server started, Redis version " REDIS_VERSION);
-#ifdef __linux__
-    linuxOvercommitMemoryWarning();
-#endif
-    if (server.appendonly) {
-        if (loadAppendOnlyFile(server.appendfilename) == REDIS_OK)
-            redisLog(REDIS_NOTICE,"DB loaded from append only file");
-    } else {
-        if (rdbLoad(server.dbfilename) == REDIS_OK)
-            redisLog(REDIS_NOTICE,"DB loaded from disk");
-    }
-    if (aeCreateFileEvent(server.el, server.fd, AE_READABLE,
-        acceptHandler, NULL, NULL) == AE_ERR) oom("creating file event");
-    redisLog(REDIS_NOTICE,"The server is now ready to accept connections on port %d", server.port);
-    aeMain(server.el);
-    aeDeleteEventLoop(server.el);
-    return 0;
-}
diff --git a/staticsymbols.h b/staticsymbols.h
new file mode 100644 (file)
index 0000000..b1fc36f
--- /dev/null
@@ -0,0 +1,189 @@
+static struct redisFunctionSym symsTable[] = {
+{"acceptHandler",(unsigned long)acceptHandler},
+{"addReply",(unsigned long)addReply},
+{"addReplyBulkLen",(unsigned long)addReplyBulkLen},
+{"addReplySds",(unsigned long)addReplySds},
+{"appendServerSaveParams",(unsigned long)appendServerSaveParams},
+{"authCommand",(unsigned long)authCommand},
+{"bgsaveCommand",(unsigned long)bgsaveCommand},
+{"closeTimedoutClients",(unsigned long)closeTimedoutClients},
+{"compareStringObjects",(unsigned long)compareStringObjects},
+{"createClient",(unsigned long)createClient},
+{"createListObject",(unsigned long)createListObject},
+{"createObject",(unsigned long)createObject},
+{"createSetObject",(unsigned long)createSetObject},
+{"createSharedObjects",(unsigned long)createSharedObjects},
+{"createSortOperation",(unsigned long)createSortOperation},
+{"createStringObject",(unsigned long)createStringObject},
+{"createZsetObject",(unsigned long)createZsetObject},
+{"daemonize",(unsigned long)daemonize},
+{"dbsizeCommand",(unsigned long)dbsizeCommand},
+{"debugCommand",(unsigned long)debugCommand},
+{"decrCommand",(unsigned long)decrCommand},
+{"decrRefCount",(unsigned long)decrRefCount},
+{"decrbyCommand",(unsigned long)decrbyCommand},
+{"delCommand",(unsigned long)delCommand},
+{"deleteIfVolatile",(unsigned long)deleteIfVolatile},
+{"deleteKey",(unsigned long)deleteKey},
+{"dictEncObjKeyCompare",(unsigned long)dictEncObjKeyCompare},
+{"dictObjKeyCompare",(unsigned long)dictObjKeyCompare},
+{"dictRedisObjectDestructor",(unsigned long)dictRedisObjectDestructor},
+{"dictVanillaFree",(unsigned long)dictVanillaFree},
+{"dupClientReplyValue",(unsigned long)dupClientReplyValue},
+{"echoCommand",(unsigned long)echoCommand},
+{"existsCommand",(unsigned long)existsCommand},
+{"expireCommand",(unsigned long)expireCommand},
+{"expireGenericCommand",(unsigned long)expireGenericCommand},
+{"expireIfNeeded",(unsigned long)expireIfNeeded},
+{"expireatCommand",(unsigned long)expireatCommand},
+{"feedAppendOnlyFile",(unsigned long)feedAppendOnlyFile},
+{"findFuncName",(unsigned long)findFuncName},
+{"flushallCommand",(unsigned long)flushallCommand},
+{"flushdbCommand",(unsigned long)flushdbCommand},
+{"freeClient",(unsigned long)freeClient},
+{"freeClientArgv",(unsigned long)freeClientArgv},
+{"freeFakeClient",(unsigned long)freeFakeClient},
+{"freeHashObject",(unsigned long)freeHashObject},
+{"freeListObject",(unsigned long)freeListObject},
+{"freeMemoryIfNeeded",(unsigned long)freeMemoryIfNeeded},
+{"freeSetObject",(unsigned long)freeSetObject},
+{"freeStringObject",(unsigned long)freeStringObject},
+{"freeZsetObject",(unsigned long)freeZsetObject},
+{"getCommand",(unsigned long)getCommand},
+{"getDecodedObject",(unsigned long)getDecodedObject},
+{"getExpire",(unsigned long)getExpire},
+{"getMcontextEip",(unsigned long)getMcontextEip},
+{"getsetCommand",(unsigned long)getsetCommand},
+{"glueReplyBuffersIfNeeded",(unsigned long)glueReplyBuffersIfNeeded},
+{"htNeedsResize",(unsigned long)htNeedsResize},
+{"incrCommand",(unsigned long)incrCommand},
+{"incrDecrCommand",(unsigned long)incrDecrCommand},
+{"incrRefCount",(unsigned long)incrRefCount},
+{"incrbyCommand",(unsigned long)incrbyCommand},
+{"infoCommand",(unsigned long)infoCommand},
+{"initServer",(unsigned long)initServer},
+{"initServerConfig",(unsigned long)initServerConfig},
+{"isStringRepresentableAsLong",(unsigned long)isStringRepresentableAsLong},
+{"keysCommand",(unsigned long)keysCommand},
+{"lastsaveCommand",(unsigned long)lastsaveCommand},
+{"lindexCommand",(unsigned long)lindexCommand},
+{"llenCommand",(unsigned long)llenCommand},
+{"loadServerConfig",(unsigned long)loadServerConfig},
+{"lookupKey",(unsigned long)lookupKey},
+{"lookupKeyByPattern",(unsigned long)lookupKeyByPattern},
+{"lookupKeyRead",(unsigned long)lookupKeyRead},
+{"lookupKeyWrite",(unsigned long)lookupKeyWrite},
+{"lpopCommand",(unsigned long)lpopCommand},
+{"lpushCommand",(unsigned long)lpushCommand},
+{"lrangeCommand",(unsigned long)lrangeCommand},
+{"lremCommand",(unsigned long)lremCommand},
+{"lsetCommand",(unsigned long)lsetCommand},
+{"ltrimCommand",(unsigned long)ltrimCommand},
+{"mgetCommand",(unsigned long)mgetCommand},
+{"monitorCommand",(unsigned long)monitorCommand},
+{"moveCommand",(unsigned long)moveCommand},
+{"msetCommand",(unsigned long)msetCommand},
+{"msetGenericCommand",(unsigned long)msetGenericCommand},
+{"msetnxCommand",(unsigned long)msetnxCommand},
+{"oom",(unsigned long)oom},
+{"pingCommand",(unsigned long)pingCommand},
+{"popGenericCommand",(unsigned long)popGenericCommand},
+{"processCommand",(unsigned long)processCommand},
+{"processInputBuffer",(unsigned long)processInputBuffer},
+{"pushGenericCommand",(unsigned long)pushGenericCommand},
+{"qsortCompareSetsByCardinality",(unsigned long)qsortCompareSetsByCardinality},
+{"randomkeyCommand",(unsigned long)randomkeyCommand},
+{"rdbLoad",(unsigned long)rdbLoad},
+{"rdbLoadDoubleValue",(unsigned long)rdbLoadDoubleValue},
+{"rdbLoadIntegerObject",(unsigned long)rdbLoadIntegerObject},
+{"rdbLoadLen",(unsigned long)rdbLoadLen},
+{"rdbLoadLzfStringObject",(unsigned long)rdbLoadLzfStringObject},
+{"rdbLoadStringObject",(unsigned long)rdbLoadStringObject},
+{"rdbLoadTime",(unsigned long)rdbLoadTime},
+{"rdbLoadType",(unsigned long)rdbLoadType},
+{"rdbRemoveTempFile",(unsigned long)rdbRemoveTempFile},
+{"rdbSave",(unsigned long)rdbSave},
+{"rdbSaveBackground",(unsigned long)rdbSaveBackground},
+{"rdbSaveDoubleValue",(unsigned long)rdbSaveDoubleValue},
+{"rdbSaveLen",(unsigned long)rdbSaveLen},
+{"rdbSaveLzfStringObject",(unsigned long)rdbSaveLzfStringObject},
+{"rdbSaveStringObject",(unsigned long)rdbSaveStringObject},
+{"rdbSaveStringObjectRaw",(unsigned long)rdbSaveStringObjectRaw},
+{"rdbSaveTime",(unsigned long)rdbSaveTime},
+{"rdbSaveType",(unsigned long)rdbSaveType},
+{"rdbTryIntegerEncoding",(unsigned long)rdbTryIntegerEncoding},
+{"readQueryFromClient",(unsigned long)readQueryFromClient},
+{"redisLog",(unsigned long)redisLog},
+{"removeExpire",(unsigned long)removeExpire},
+{"renameCommand",(unsigned long)renameCommand},
+{"renameGenericCommand",(unsigned long)renameGenericCommand},
+{"renamenxCommand",(unsigned long)renamenxCommand},
+{"replicationFeedSlaves",(unsigned long)replicationFeedSlaves},
+{"resetClient",(unsigned long)resetClient},
+{"resetServerSaveParams",(unsigned long)resetServerSaveParams},
+{"rpopCommand",(unsigned long)rpopCommand},
+{"rpushCommand",(unsigned long)rpushCommand},
+{"saddCommand",(unsigned long)saddCommand},
+{"saveCommand",(unsigned long)saveCommand},
+{"scardCommand",(unsigned long)scardCommand},
+{"sdiffCommand",(unsigned long)sdiffCommand},
+{"sdiffstoreCommand",(unsigned long)sdiffstoreCommand},
+{"sdsDictKeyCompare",(unsigned long)sdsDictKeyCompare},
+{"segvHandler",(unsigned long)segvHandler},
+{"selectCommand",(unsigned long)selectCommand},
+{"selectDb",(unsigned long)selectDb},
+{"sendBulkToSlave",(unsigned long)sendBulkToSlave},
+{"sendReplyToClient",(unsigned long)sendReplyToClient},
+{"serverCron",(unsigned long)serverCron},
+{"setCommand",(unsigned long)setCommand},
+{"setExpire",(unsigned long)setExpire},
+{"setGenericCommand",(unsigned long)setGenericCommand},
+{"setnxCommand",(unsigned long)setnxCommand},
+{"setupSigSegvAction",(unsigned long)setupSigSegvAction},
+{"shutdownCommand",(unsigned long)shutdownCommand},
+{"sinterCommand",(unsigned long)sinterCommand},
+{"sinterGenericCommand",(unsigned long)sinterGenericCommand},
+{"sinterstoreCommand",(unsigned long)sinterstoreCommand},
+{"sismemberCommand",(unsigned long)sismemberCommand},
+{"slaveofCommand",(unsigned long)slaveofCommand},
+{"smoveCommand",(unsigned long)smoveCommand},
+{"sortCommand",(unsigned long)sortCommand},
+{"sortCompare",(unsigned long)sortCompare},
+{"spopCommand",(unsigned long)spopCommand},
+{"srandmemberCommand",(unsigned long)srandmemberCommand},
+{"sremCommand",(unsigned long)sremCommand},
+{"stringObjectLen",(unsigned long)stringObjectLen},
+{"sunionCommand",(unsigned long)sunionCommand},
+{"sunionDiffGenericCommand",(unsigned long)sunionDiffGenericCommand},
+{"sunionstoreCommand",(unsigned long)sunionstoreCommand},
+{"syncCommand",(unsigned long)syncCommand},
+{"syncRead",(unsigned long)syncRead},
+{"syncReadLine",(unsigned long)syncReadLine},
+{"syncWithMaster",(unsigned long)syncWithMaster},
+{"syncWrite",(unsigned long)syncWrite},
+{"tryObjectEncoding",(unsigned long)tryObjectEncoding},
+{"tryObjectSharing",(unsigned long)tryObjectSharing},
+{"tryResizeHashTables",(unsigned long)tryResizeHashTables},
+{"ttlCommand",(unsigned long)ttlCommand},
+{"typeCommand",(unsigned long)typeCommand},
+{"updateSlavesWaitingBgsave",(unsigned long)updateSlavesWaitingBgsave},
+{"yesnotoi",(unsigned long)yesnotoi},
+{"zaddCommand",(unsigned long)zaddCommand},
+{"zcardCommand",(unsigned long)zcardCommand},
+{"zrangeCommand",(unsigned long)zrangeCommand},
+{"zrangeGenericCommand",(unsigned long)zrangeGenericCommand},
+{"zrangebyscoreCommand",(unsigned long)zrangebyscoreCommand},
+{"zremCommand",(unsigned long)zremCommand},
+{"zremrangebyscoreCommand",(unsigned long)zremrangebyscoreCommand},
+{"zrevrangeCommand",(unsigned long)zrevrangeCommand},
+{"zscoreCommand",(unsigned long)zscoreCommand},
+{"zslCreate",(unsigned long)zslCreate},
+{"zslCreateNode",(unsigned long)zslCreateNode},
+{"zslDelete",(unsigned long)zslDelete},
+{"zslFirstWithScore",(unsigned long)zslFirstWithScore},
+{"zslFree",(unsigned long)zslFree},
+{"zslFreeNode",(unsigned long)zslFreeNode},
+{"zslInsert",(unsigned long)zslInsert},
+{"zslRandomLevel",(unsigned long)zslRandomLevel},
+{NULL,0}
+};
diff --git a/utils/build-static-symbols.tcl b/utils/build-static-symbols.tcl
new file mode 100644 (file)
index 0000000..e634cbe
--- /dev/null
@@ -0,0 +1,22 @@
+# Build a symbol table for static symbols of redis.c
+# Useful to get stack traces on segfault without a debugger. See redis.c
+# for more information.
+#
+# Copyright(C) 2009 Salvatore Sanfilippo, under the BSD license.
+
+set fd [open redis.c]
+set symlist {}
+while {[gets $fd line] != -1} {
+    if {[regexp {^static +[A-z0-9]+[ *]+([A-z0-9]*)\(} $line - sym]} {
+        lappend symlist $sym
+    }
+}
+set symlist [lsort -unique $symlist]
+puts "static struct redisFunctionSym symsTable\[\] = {"
+foreach sym $symlist {
+    puts "{\"$sym\",(unsigned long)$sym},"
+}
+puts "{NULL,0}"
+puts "};"
+
+close $fd