mirror of
https://github.com/fluencelabs/redis
synced 2025-05-30 10:41:19 +00:00
On crash print information about the current client (if any), command vector, and object associated to first argument assuming it is a key.
This commit is contained in:
parent
e1849b6456
commit
fbfe656236
21
src/debug.c
21
src/debug.c
@ -337,6 +337,27 @@ void debugCommand(redisClient *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void redisLogObjectDebugInfo(robj *o) {
|
||||||
|
redisLog(REDIS_WARNING,"Object type: %d", o->type);
|
||||||
|
redisLog(REDIS_WARNING,"Object encoding: %d", o->encoding);
|
||||||
|
redisLog(REDIS_WARNING,"Object refcount: %d", o->refcount);
|
||||||
|
if (o->type == REDIS_STRING && o->encoding == REDIS_ENCODING_RAW) {
|
||||||
|
redisLog(REDIS_WARNING,"Object raw string len: %d", sdslen(o->ptr));
|
||||||
|
if (sdslen(o->ptr) < 4096)
|
||||||
|
redisLog(REDIS_WARNING,"Object raw string content: \"%s\"", (char*)o->ptr);
|
||||||
|
} else if (o->type == REDIS_LIST) {
|
||||||
|
redisLog(REDIS_WARNING,"List length: %d", (int) listTypeLength(o));
|
||||||
|
} else if (o->type == REDIS_SET) {
|
||||||
|
redisLog(REDIS_WARNING,"Set size: %d", (int) setTypeSize(o));
|
||||||
|
} else if (o->type == REDIS_HASH) {
|
||||||
|
redisLog(REDIS_WARNING,"Hash size: %d", (int) hashTypeLength(o));
|
||||||
|
} else if (o->type == REDIS_ZSET) {
|
||||||
|
redisLog(REDIS_WARNING,"Sorted set size: %d", (int) zsetLength(o));
|
||||||
|
if (o->encoding == REDIS_ENCODING_SKIPLIST)
|
||||||
|
redisLog(REDIS_WARNING,"Skiplist level: %d", (int) ((zset*)o->ptr)->zsl->level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _redisAssert(char *estr, char *file, int line) {
|
void _redisAssert(char *estr, char *file, int line) {
|
||||||
bugReportStart();
|
bugReportStart();
|
||||||
redisLog(REDIS_WARNING,"=== ASSERTION FAILED ===");
|
redisLog(REDIS_WARNING,"=== ASSERTION FAILED ===");
|
||||||
|
@ -467,6 +467,9 @@ static void freeClientArgv(redisClient *c) {
|
|||||||
void freeClient(redisClient *c) {
|
void freeClient(redisClient *c) {
|
||||||
listNode *ln;
|
listNode *ln;
|
||||||
|
|
||||||
|
/* If this is marked as current client unset it */
|
||||||
|
if (server.current_client == c) server.current_client = NULL;
|
||||||
|
|
||||||
/* Note that if the client we are freeing is blocked into a blocking
|
/* Note that if the client we are freeing is blocked into a blocking
|
||||||
* call, we have to set querybuf to NULL *before* to call
|
* call, we have to set querybuf to NULL *before* to call
|
||||||
* unblockClientWaitingData() to avoid processInputBuffer() will get
|
* unblockClientWaitingData() to avoid processInputBuffer() will get
|
||||||
@ -875,6 +878,7 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
REDIS_NOTUSED(el);
|
REDIS_NOTUSED(el);
|
||||||
REDIS_NOTUSED(mask);
|
REDIS_NOTUSED(mask);
|
||||||
|
|
||||||
|
server.current_client = c;
|
||||||
nread = read(fd, buf, REDIS_IOBUF_LEN);
|
nread = read(fd, buf, REDIS_IOBUF_LEN);
|
||||||
if (nread == -1) {
|
if (nread == -1) {
|
||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN) {
|
||||||
@ -893,6 +897,7 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
c->querybuf = sdscatlen(c->querybuf,buf,nread);
|
c->querybuf = sdscatlen(c->querybuf,buf,nread);
|
||||||
c->lastinteraction = time(NULL);
|
c->lastinteraction = time(NULL);
|
||||||
} else {
|
} else {
|
||||||
|
server.current_client = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sdslen(c->querybuf) > server.client_max_querybuf_len) {
|
if (sdslen(c->querybuf) > server.client_max_querybuf_len) {
|
||||||
@ -906,6 +911,7 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
processInputBuffer(c);
|
processInputBuffer(c);
|
||||||
|
server.current_client = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getClientsMaxBuffers(unsigned long *longest_output_list,
|
void getClientsMaxBuffers(unsigned long *longest_output_list,
|
||||||
|
40
src/redis.c
40
src/redis.c
@ -716,8 +716,11 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
|
|||||||
call(c);
|
call(c);
|
||||||
resetClient(c);
|
resetClient(c);
|
||||||
/* There may be more data to process in the input buffer. */
|
/* There may be more data to process in the input buffer. */
|
||||||
if (c->querybuf && sdslen(c->querybuf) > 0)
|
if (c->querybuf && sdslen(c->querybuf) > 0) {
|
||||||
|
server.current_client = c;
|
||||||
processInputBuffer(c);
|
processInputBuffer(c);
|
||||||
|
server.current_client = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -907,6 +910,7 @@ void initServer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
server.mainthread = pthread_self();
|
server.mainthread = pthread_self();
|
||||||
|
server.current_client = NULL;
|
||||||
server.clients = listCreate();
|
server.clients = listCreate();
|
||||||
server.slaves = listCreate();
|
server.slaves = listCreate();
|
||||||
server.monitors = listCreate();
|
server.monitors = listCreate();
|
||||||
@ -1797,6 +1801,40 @@ static void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
|
|||||||
redisLog(REDIS_WARNING, clients);
|
redisLog(REDIS_WARNING, clients);
|
||||||
/* Don't sdsfree() strings to avoid a crash. Memory may be corrupted. */
|
/* Don't sdsfree() strings to avoid a crash. Memory may be corrupted. */
|
||||||
|
|
||||||
|
/* Log CURRENT CLIENT info */
|
||||||
|
if (server.current_client) {
|
||||||
|
redisClient *cc = server.current_client;
|
||||||
|
sds client;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
redisLog(REDIS_WARNING, "--- CURRENT CLIENT INFO");
|
||||||
|
client = getClientInfoString(cc);
|
||||||
|
redisLog(REDIS_WARNING,"client: %s", client);
|
||||||
|
/* Missing sdsfree(client) to avoid crash if memory is corrupted. */
|
||||||
|
for (j = 0; j < cc->argc; j++) {
|
||||||
|
robj *decoded;
|
||||||
|
|
||||||
|
decoded = getDecodedObject(cc->argv[j]);
|
||||||
|
redisLog(REDIS_WARNING,"argv[%d]: '%s'", j, (char*)decoded->ptr);
|
||||||
|
decrRefCount(decoded);
|
||||||
|
}
|
||||||
|
/* Check if the first argument, usually a key, is found inside the
|
||||||
|
* selected DB, and if so print info about the associated object. */
|
||||||
|
if (cc->argc >= 1) {
|
||||||
|
robj *val, *key;
|
||||||
|
dictEntry *de;
|
||||||
|
|
||||||
|
key = getDecodedObject(cc->argv[1]);
|
||||||
|
de = dictFind(cc->db->dict, key->ptr);
|
||||||
|
if (de) {
|
||||||
|
val = dictGetEntryVal(de);
|
||||||
|
redisLog(REDIS_WARNING,"key '%s' found in DB containing the following object:", key->ptr);
|
||||||
|
redisLogObjectDebugInfo(val);
|
||||||
|
}
|
||||||
|
decrRefCount(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
redisLog(REDIS_WARNING,
|
redisLog(REDIS_WARNING,
|
||||||
"=== REDIS BUG REPORT END. Make sure to include from START to END. ===\n\n"
|
"=== REDIS BUG REPORT END. Make sure to include from START to END. ===\n\n"
|
||||||
" Please report the crash opening an issue on github:\n\n"
|
" Please report the crash opening an issue on github:\n\n"
|
||||||
|
@ -400,6 +400,7 @@ struct redisServer {
|
|||||||
/* Fast pointers to often looked up command */
|
/* Fast pointers to often looked up command */
|
||||||
struct redisCommand *delCommand, *multiCommand;
|
struct redisCommand *delCommand, *multiCommand;
|
||||||
list *slaves, *monitors;
|
list *slaves, *monitors;
|
||||||
|
redisClient *current_client; /* Current client, only used on crash report */
|
||||||
char neterr[ANET_ERR_LEN];
|
char neterr[ANET_ERR_LEN];
|
||||||
aeEventLoop *el;
|
aeEventLoop *el;
|
||||||
int cronloops; /* number of times the cron function run */
|
int cronloops; /* number of times the cron function run */
|
||||||
@ -1072,4 +1073,6 @@ void *malloc(size_t size) __attribute__ ((deprecated));
|
|||||||
void *realloc(void *ptr, size_t size) __attribute__ ((deprecated));
|
void *realloc(void *ptr, size_t size) __attribute__ ((deprecated));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void redisLogObjectDebugInfo(robj *o);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user