/* 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;
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]);
* it later */
lenobj = createObject(REDIS_STRING,NULL);
addReply(c,lenobj);
+ decrRefCount(lenobj);
while(ln && ln->score <= max) {
ele = ln->obj;
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;
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"
"role:%s\r\n"
,REDIS_VERSION,
(sizeof(long) == 8) ? "64" : "32",
+ aeGetApiName(),
uptime,
uptime/(3600*24),
listLength(server.clients)-listLength(server.slaves),
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);
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 */
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);
}