diff options
Diffstat (limited to 'src/debug.c')
-rw-r--r-- | src/debug.c | 80 |
1 files changed, 57 insertions, 23 deletions
diff --git a/src/debug.c b/src/debug.c index 5d5029f5a..5a8190c96 100644 --- a/src/debug.c +++ b/src/debug.c @@ -285,25 +285,27 @@ void computeDatasetDigest(unsigned char *final) { void debugCommand(client *c) { if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"help")) { const char *help[] = { -"assert -- Crash by assertion failed.", -"change-repl-id -- Change the replication IDs of the instance. Dangerous, should be used only for testing the replication subsystem.", -"crash-and-recovery <milliseconds> -- Hard crash and restart after <milliseconds> delay.", -"digest -- Outputs an hex signature representing the current DB content.", -"htstats <dbid> -- Return hash table statistics of the specified Redis database.", -"loadaof -- Flush the AOF buffers on disk and reload the AOF in memory.", -"lua-always-replicate-commands (0|1) -- Setting it to 1 makes Lua replication defaulting to replicating single commands, without the script having to enable effects replication.", -"object <key> -- Show low level info about key and associated value.", -"panic -- Crash the server simulating a panic.", -"populate <count> [prefix] [size] -- Create <count> string keys named key:<num>. If a prefix is specified is used instead of the 'key' prefix.", -"reload -- Save the RDB on disk and reload it back in memory.", -"restart -- Graceful restart: save config, db, restart.", -"sdslen <key> -- Show low level SDS string info representing key and value.", -"segfault -- Crash the server with sigsegv.", -"set-active-expire (0|1) -- Setting it to 0 disables expiring keys in background when they are not accessed (otherwise the Redis behavior). Setting it to 1 reenables back the default.", -"sleep <seconds> -- Stop the server for <seconds>. Decimals allowed.", -"structsize -- Return the size of different Redis core C structures.", -"ziplist <key> -- Show low level info about the ziplist encoding.", -"error <string> -- Return a Redis protocol error with <string> as message. Useful for clients unit tests to simulate Redis errors.", +"ASSERT -- Crash by assertion failed.", +"CHANGE-REPL-ID -- Change the replication IDs of the instance. Dangerous, should be used only for testing the replication subsystem.", +"CRASH-AND-RECOVER <milliseconds> -- Hard crash and restart after <milliseconds> delay.", +"DIGEST -- Output a hex signature representing the current DB content.", +"ERROR <string> -- Return a Redis protocol error with <string> as message. Useful for clients unit tests to simulate Redis errors.", +"LOG <message> -- write message to the server log.", +"HTSTATS <dbid> -- Return hash table statistics of the specified Redis database.", +"HTSTATS-KEY <key> -- Like htstats but for the hash table stored as key's value.", +"LOADAOF -- Flush the AOF buffers on disk and reload the AOF in memory.", +"LUA-ALWAYS-REPLICATE-COMMANDS <0|1> -- Setting it to 1 makes Lua replication defaulting to replicating single commands, without the script having to enable effects replication.", +"OBJECT <key> -- Show low level info about key and associated value.", +"PANIC -- Crash the server simulating a panic.", +"POPULATE <count> [prefix] [size] -- Create <count> string keys named key:<num>. If a prefix is specified is used instead of the 'key' prefix.", +"RELOAD -- Save the RDB on disk and reload it back in memory.", +"RESTART -- Graceful restart: save config, db, restart.", +"SDSLEN <key> -- Show low level SDS string info representing key and value.", +"SEGFAULT -- Crash the server with sigsegv.", +"SET-ACTIVE-EXPIRE <0|1> -- Setting it to 0 disables expiring keys in background when they are not accessed (otherwise the Redis behavior). Setting it to 1 reenables back the default.", +"SLEEP <seconds> -- Stop the server for <seconds>. Decimals allowed.", +"STRUCTSIZE -- Return the size of different Redis core C structures.", +"ZIPLIST <key> -- Show low level info about the ziplist encoding.", NULL }; addReplyHelp(c, help); @@ -332,6 +334,9 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"assert")) { if (c->argc >= 3) c->argv[2] = tryObjectEncoding(c->argv[2]); serverAssertWithInfo(c,c->argv[0],1 == 2); + } else if (!strcasecmp(c->argv[1]->ptr,"log") && c->argc == 3) { + serverLog(LL_WARNING, "DEBUG LOG: %s", (char*)c->argv[2]->ptr); + addReply(c,shared.ok); } else if (!strcasecmp(c->argv[1]->ptr,"reload")) { rdbSaveInfo rsi, *rsiptr; rsiptr = rdbPopulateSaveInfo(&rsi); @@ -350,7 +355,7 @@ NULL serverLog(LL_WARNING,"DB reloaded by DEBUG RELOAD"); addReply(c,shared.ok); } else if (!strcasecmp(c->argv[1]->ptr,"loadaof")) { - if (server.aof_state == AOF_ON) flushAppendOnlyFile(1); + if (server.aof_state != AOF_OFF) flushAppendOnlyFile(1); emptyDb(-1,EMPTYDB_NO_FLAGS,NULL); aeDeleteFileEvent(server.el,c->fd,AE_READABLE); int ret = loadAppendOnlyFile(server.aof_filename); @@ -553,14 +558,41 @@ NULL stats = sdscat(stats,buf); addReplyBulkSds(c,stats); + } else if (!strcasecmp(c->argv[1]->ptr,"htstats-key") && c->argc == 3) { + robj *o; + dict *ht = NULL; + + if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nokeyerr)) + == NULL) return; + + /* Get the hash table reference from the object, if possible. */ + switch (o->encoding) { + case OBJ_ENCODING_SKIPLIST: + { + zset *zs = o->ptr; + ht = zs->dict; + } + break; + case OBJ_ENCODING_HT: + ht = o->ptr; + break; + } + + if (ht == NULL) { + addReplyError(c,"The value stored at the specified key is not " + "represented using an hash table"); + } else { + char buf[4096]; + dictGetStats(buf,sizeof(buf),ht); + addReplyBulkCString(c,buf); + } } else if (!strcasecmp(c->argv[1]->ptr,"change-repl-id") && c->argc == 2) { serverLog(LL_WARNING,"Changing replication IDs after receiving DEBUG change-repl-id"); changeReplicationId(); clearReplicationId2(); addReply(c,shared.ok); } else { - addReplyErrorFormat(c, "Unknown subcommand or wrong number of arguments for '%s'. Try DEBUG HELP", - (char*)c->argv[1]->ptr); + addReplySubcommandSyntaxError(c); return; } } @@ -694,6 +726,8 @@ static void *getMcontextEip(ucontext_t *uc) { return (void*) uc->uc_mcontext.sc_ip; #elif defined(__arm__) /* Linux ARM */ return (void*) uc->uc_mcontext.arm_pc; + #elif defined(__aarch64__) /* Linux AArch64 */ + return (void*) uc->uc_mcontext.pc; #endif #else return NULL; @@ -1052,7 +1086,7 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) { infostring = genRedisInfoString("all"); serverLogRaw(LL_WARNING|LL_RAW, infostring); serverLogRaw(LL_WARNING|LL_RAW, "\n------ CLIENT LIST OUTPUT ------\n"); - clients = getAllClientsInfoString(); + clients = getAllClientsInfoString(-1); serverLogRaw(LL_WARNING|LL_RAW, clients); sdsfree(infostring); sdsfree(clients); |