SIGSEGV handler refactored so that we can reuse stack trace and current client logging functionalities in other contexts.

This commit is contained in:
antirez 2012-03-27 10:33:45 +02:00
parent ca09ad4d64
commit a323870450

View File

@ -558,21 +558,11 @@ void logRegisters(ucontext_t *uc) {
#endif
}
void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
/* Logs the stack trace using the backtrace() call. */
void logStackTrace(ucontext_t *uc) {
void *trace[100];
char **messages = NULL;
int i, trace_size = 0;
ucontext_t *uc = (ucontext_t*) secret;
sds infostring, clients;
struct sigaction act;
REDIS_NOTUSED(info);
bugReportStart();
redisLog(REDIS_WARNING,
" Redis %s crashed by signal: %d", REDIS_VERSION, sig);
redisLog(REDIS_WARNING,
" Failed assertion: %s (%s:%d)", server.assert_failed,
server.assert_file, server.assert_line);
char **messages = NULL;
/* Generate the stack trace */
trace_size = backtrace(trace, 100);
@ -585,20 +575,14 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
redisLog(REDIS_WARNING, "--- STACK TRACE");
for (i=1; i<trace_size; ++i)
redisLog(REDIS_WARNING,"%s", messages[i]);
}
/* Log INFO and CLIENT LIST */
redisLog(REDIS_WARNING, "--- INFO OUTPUT");
infostring = genRedisInfoString("all");
infostring = sdscatprintf(infostring, "hash_init_value: %u\n",
dictGetHashFunctionSeed());
redisLogRaw(REDIS_WARNING, infostring);
redisLog(REDIS_WARNING, "--- CLIENT LIST OUTPUT");
clients = getAllClientsInfoString();
redisLogRaw(REDIS_WARNING, clients);
/* Don't sdsfree() strings to avoid a crash. Memory may be corrupted. */
/* Log information about the "current" client, that is, the client that is
* currently being served by Redis. May be NULL if Redis is not serving a
* client right now. */
void logCurrentClient(void) {
if (server.current_client == NULL) return;
/* Log CURRENT CLIENT info */
if (server.current_client) {
redisClient *cc = server.current_client;
sds client;
int j;
@ -606,7 +590,7 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
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. */
sdsfree(client);
for (j = 0; j < cc->argc; j++) {
robj *decoded;
@ -631,6 +615,37 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
}
}
void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
ucontext_t *uc = (ucontext_t*) secret;
sds infostring, clients;
struct sigaction act;
REDIS_NOTUSED(info);
bugReportStart();
redisLog(REDIS_WARNING,
" Redis %s crashed by signal: %d", REDIS_VERSION, sig);
redisLog(REDIS_WARNING,
" Failed assertion: %s (%s:%d)", server.assert_failed,
server.assert_file, server.assert_line);
/* Log the stack trace */
logStackTrace(uc);
/* Log INFO and CLIENT LIST */
redisLog(REDIS_WARNING, "--- INFO OUTPUT");
infostring = genRedisInfoString("all");
infostring = sdscatprintf(infostring, "hash_init_value: %u\n",
dictGetHashFunctionSeed());
redisLogRaw(REDIS_WARNING, infostring);
redisLog(REDIS_WARNING, "--- CLIENT LIST OUTPUT");
clients = getAllClientsInfoString();
redisLogRaw(REDIS_WARNING, clients);
sdsfree(infostring);
sdsfree(clients);
/* Log the current client */
logCurrentClient();
/* Log dump of processor registers */
logRegisters(uc);