mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 08:08:53 -05:00
Log from signal handlers is now safer.
This commit is contained in:
parent
1043c8064b
commit
a7d12cbaf1
15
src/debug.c
15
src/debug.c
@ -682,25 +682,16 @@ void watchdogSignalHandler(int sig, siginfo_t *info, void *secret) {
|
||||
REDIS_NOTUSED(info);
|
||||
REDIS_NOTUSED(sig);
|
||||
sds st, log;
|
||||
time_t now = time(NULL);
|
||||
char date[128];
|
||||
FILE *fp;
|
||||
|
||||
fp = (server.logfile == NULL) ? stdout : fopen(server.logfile,"a");
|
||||
if (fp == NULL) return;
|
||||
|
||||
strftime(date,sizeof(date),"%d %b %H:%M:%S",localtime(&now));
|
||||
log = sdscatprintf(sdsempty(),
|
||||
"\n--- WATCHDOG TIMER EXPIRED (%s) ---\n",date);
|
||||
log = sdsnew("\n--- WATCHDOG TIMER EXPIRED ---\n");
|
||||
#ifdef HAVE_BACKTRACE
|
||||
st = getStackTrace(uc);
|
||||
#else
|
||||
st = sdsnew("Sorry: no support for backtrace().\n");
|
||||
#endif
|
||||
log = sdscatsds(log,st);
|
||||
log = sdscat(log,"------\n\n");
|
||||
fprintf(fp,"%s",log);
|
||||
if (server.logfile) fclose(fp);
|
||||
log = sdscat(log,"------\n");
|
||||
redisLogFromHandler(REDIS_WARNING,log);
|
||||
sdsfree(st);
|
||||
sdsfree(log);
|
||||
}
|
||||
|
30
src/redis.c
30
src/redis.c
@ -293,6 +293,34 @@ void redisLog(int level, const char *fmt, ...) {
|
||||
redisLogRaw(level,msg);
|
||||
}
|
||||
|
||||
/* Log a fixed message without printf-alike capabilities, in a way that is
|
||||
* safe to call from a signal handler.
|
||||
*
|
||||
* We actually use this only for signals that are not fatal from the point
|
||||
* of view of Redis. Signals that are going to kill the server anyway and
|
||||
* where we need printf-alike features are served by redisLog(). */
|
||||
void redisLogFromHandler(int level, const char *msg) {
|
||||
int fd;
|
||||
char buf[64];
|
||||
|
||||
if ((level&0xff) < server.verbosity ||
|
||||
(server.logfile == NULL && server.daemonize)) return;
|
||||
fd = server.logfile ?
|
||||
open(server.logfile, O_APPEND|O_CREAT|O_WRONLY, 0644) :
|
||||
STDIN_FILENO;
|
||||
if (fd == -1) return;
|
||||
ll2string(buf,sizeof(buf),getpid());
|
||||
write(fd,"[",1);
|
||||
write(fd,buf,strlen(buf));
|
||||
write(fd," | signal handler] (",20);
|
||||
ll2string(buf,sizeof(buf),time(NULL));
|
||||
write(fd,buf,strlen(buf));
|
||||
write(fd,") ",2);
|
||||
write(fd,msg,strlen(msg));
|
||||
write(fd,"\n",1);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* Redis generally does not try to recover from out of memory conditions
|
||||
* when allocating objects or strings, it is not clear if it will be possible
|
||||
* to report this condition to the client since the networking layer itself
|
||||
@ -2282,7 +2310,7 @@ void redisAsciiArt(void) {
|
||||
static void sigtermHandler(int sig) {
|
||||
REDIS_NOTUSED(sig);
|
||||
|
||||
redisLog(REDIS_WARNING,"Received SIGTERM, scheduling shutdown...");
|
||||
redisLogFromHandler(REDIS_WARNING,"Received SIGTERM, scheduling shutdown...");
|
||||
server.shutdown_asap = 1;
|
||||
}
|
||||
|
||||
|
@ -1004,6 +1004,7 @@ void alsoPropagate(struct redisCommand *cmd, int dbid, robj **argv, int argc, in
|
||||
int prepareForShutdown();
|
||||
void redisLog(int level, const char *fmt, ...);
|
||||
void redisLogRaw(int level, const char *msg);
|
||||
void redisLogFromHandler(int level, const char *msg);
|
||||
void usage();
|
||||
void updateDictResizePolicy(void);
|
||||
int htNeedsResize(dict *dict);
|
||||
|
Loading…
Reference in New Issue
Block a user