]> git.saurik.com Git - redis.git/blobdiff - redis.c
TODO updated
[redis.git] / redis.c
diff --git a/redis.c b/redis.c
index bcde90c39faa89aa22ed44074c327ad6bc6a5c7e..98434620fae24652f08a07aa283c55467f30350d 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -2309,7 +2309,11 @@ static robj *getDecodedObject(robj *o) {
 /* Compare two string objects via strcmp() or alike.
  * Note that the objects may be integer-encoded. In such a case we
  * use snprintf() to get a string representation of the numbers on the stack
- * and compare the strings, it's much faster than calling getDecodedObject(). */
+ * and compare the strings, it's much faster than calling getDecodedObject().
+ *
+ * Important note: if objects are not integer encoded, but binary-safe strings,
+ * sdscmp() from sds.c will apply memcmp() so this function ca be considered
+ * binary safe. */
 static int compareStringObjects(robj *a, robj *b) {
     assert(a->type == REDIS_STRING && b->type == REDIS_STRING);
     char bufa[128], bufb[128], *astr, *bstr;
@@ -3055,6 +3059,7 @@ static void msetGenericCommand(redisClient *c, int nx) {
     for (j = 1; j < c->argc; j += 2) {
         int retval;
 
+        tryObjectEncoding(c->argv[j+1]);
         retval = dictAdd(c->db->dict,c->argv[j],c->argv[j+1]);
         if (retval == DICT_ERR) {
             dictReplace(c->db->dict,c->argv[j],c->argv[j+1]);
@@ -4582,6 +4587,7 @@ static void zrangebyscoreCommand(redisClient *c) {
              * it later */
             lenobj = createObject(REDIS_STRING,NULL);
             addReply(c,lenobj);
+            decrRefCount(lenobj);
 
             while(ln && ln->score <= max) {
                 ele = ln->obj;
@@ -5005,7 +5011,10 @@ static void sortCommand(redisClient *c) {
     zfree(vector);
 }
 
-static void infoCommand(redisClient *c) {
+/* Create the string returned by the INFO command. This is decoupled
+ * by the INFO command itself as we need to report the same information
+ * on memory corruption problems. */
+static sds genRedisInfoString(void) {
     sds info;
     time_t uptime = time(NULL)-server.stat_starttime;
     int j;
@@ -5013,6 +5022,7 @@ static void infoCommand(redisClient *c) {
     info = sdscatprintf(sdsempty(),
         "redis_version:%s\r\n"
         "arch_bits:%s\r\n"
+        "multiplexing_api:%s\r\n"
         "uptime_in_seconds:%d\r\n"
         "uptime_in_days:%d\r\n"
         "connected_clients:%d\r\n"
@@ -5026,6 +5036,7 @@ static void infoCommand(redisClient *c) {
         "role:%s\r\n"
         ,REDIS_VERSION,
         (sizeof(long) == 8) ? "64" : "32",
+        aeGetApiName(),
         uptime,
         uptime/(3600*24),
         listLength(server.clients)-listLength(server.slaves),
@@ -5061,6 +5072,11 @@ static void infoCommand(redisClient *c) {
                 j, keys, vkeys);
         }
     }
+    return info;
+}
+
+static void infoCommand(redisClient *c) {
+    sds info = genRedisInfoString();
     addReplySds(c,sdscatprintf(sdsempty(),"$%d\r\n",sdslen(info)));
     addReplySds(c,info);
     addReply(c,shared.crlf);
@@ -6170,36 +6186,16 @@ static void segvHandler(int sig, siginfo_t *info, void *secret) {
     char **messages = NULL;
     int i, trace_size = 0;
     unsigned long offset=0;
-    time_t uptime = time(NULL)-server.stat_starttime;
     ucontext_t *uc = (ucontext_t*) secret;
+    sds infostring;
     REDIS_NOTUSED(info);
 
     redisLog(REDIS_WARNING,
         "======= Ooops! Redis %s got signal: -%d- =======", REDIS_VERSION, sig);
-    redisLog(REDIS_WARNING, "%s", sdscatprintf(sdsempty(),
-        "redis_version:%s; "
-        "uptime_in_seconds:%d; "
-        "connected_clients:%d; "
-        "connected_slaves:%d; "
-        "used_memory:%zu; "
-        "changes_since_last_save:%lld; "
-        "bgsave_in_progress:%d; "
-        "last_save_time:%d; "
-        "total_connections_received:%lld; "
-        "total_commands_processed:%lld; "
-        "role:%s;"
-        ,REDIS_VERSION,
-        uptime,
-        listLength(server.clients)-listLength(server.slaves),
-        listLength(server.slaves),
-        server.usedmemory,
-        server.dirty,
-        server.bgsavechildpid != -1,
-        server.lastsave,
-        server.stat_numconnections,
-        server.stat_numcommands,
-        server.masterhost == NULL ? "master" : "slave"
-    ));
+    infostring = genRedisInfoString();
+    redisLog(REDIS_WARNING, "%s",infostring);
+    /* It's not safe to sdsfree() the returned string under memory
+     * corruption conditions. Let it leak as we are going to abort */
     
     trace_size = backtrace(trace, 100);
     /* overwrite sigaction with caller's address */
@@ -6218,7 +6214,7 @@ static void segvHandler(int sig, siginfo_t *info, void *secret) {
             redisLog(REDIS_WARNING,"%d redis-server %p %s + %d", i, trace[i], fn, (unsigned int)offset);
         }
     }
-    free(messages);
+    // free(messages); Don't call free() with possibly corrupted memory.
     exit(0);
 }