Commit 5c24d8e7 authored by Geoff Simmons's avatar Geoff Simmons

trackrdrd: signal handling with sigaction, added a handler for stack traces

           attempt to make AMQ_Worker destructor more robust
           shutdown call for the monitor thread
parent f7a8eeeb
...@@ -43,6 +43,7 @@ PKG_PROG_PKG_CONFIG ...@@ -43,6 +43,7 @@ PKG_PROG_PKG_CONFIG
# Checks for header files. # Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS([execinfo.h])
## From Varnish configure.ac ## From Varnish configure.ac
# white lie - we don't actually test it # white lie - we don't actually test it
......
...@@ -84,16 +84,25 @@ AMQ_Worker::AMQ_Worker(std::string& qName, ...@@ -84,16 +84,25 @@ AMQ_Worker::AMQ_Worker(std::string& qName,
} }
AMQ_Worker::~AMQ_Worker() { AMQ_Worker::~AMQ_Worker() {
if (connection != NULL) if (producer != NULL) {
connection->close(); delete producer;
delete producer; producer = NULL;
producer = NULL; }
delete queue; if (queue != NULL) {
queue = NULL; delete queue;
delete session; queue = NULL;
session = NULL; }
delete connection; if (session != NULL) {
connection = NULL; delete session;
session = NULL;
}
if (connection != NULL) {
#if 0
connection->close();
#endif
delete connection;
connection = NULL;
}
} }
/* XXX: Timeout */ /* XXX: Timeout */
......
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
#include "trackrdrd.h" #include "trackrdrd.h"
#include "vas.h" #include "vas.h"
static int run;
void void
*MON_StatusThread(void *arg) *MON_StatusThread(void *arg)
{ {
...@@ -48,12 +50,14 @@ void ...@@ -48,12 +50,14 @@ void
t.tv_nsec = (long)(t.tv_sec - *interval) * 10e9; t.tv_nsec = (long)(t.tv_sec - *interval) * 10e9;
LOG_Log(LOG_INFO, "Monitor thread running every %.2f secs", LOG_Log(LOG_INFO, "Monitor thread running every %.2f secs",
t.tv_sec + ((float) t.tv_nsec * 10e-9)); t.tv_sec + ((float) t.tv_nsec * 10e-9));
run = 1;
while (1) { while (run) {
int err; int err;
if (nanosleep(&t, NULL) != 0) { if (nanosleep(&t, NULL) != 0) {
if (errno == EINTR) { if (errno == EINTR) {
/* XXX: Terminate on TERM, INT, etc. */ if (run == 0)
break;
LOG_Log0(LOG_INFO, "Monitoring thread interrupted"); LOG_Log0(LOG_INFO, "Monitoring thread interrupted");
continue; continue;
} }
...@@ -73,6 +77,16 @@ void ...@@ -73,6 +77,16 @@ void
tbl.occ_hi, tbl.seen, tbl.submitted, tbl.sent, tbl.failed, tbl.occ_hi, tbl.seen, tbl.submitted, tbl.sent, tbl.failed,
tbl.wait_qfull, tbl.data_hi); tbl.wait_qfull, tbl.data_hi);
} }
LOG_Log0(LOG_INFO, "Monitoring thread exiting");
pthread_exit((void *) NULL);
}
void
MON_StatusShutdown(pthread_t monitor)
{
run = 0;
AZ(pthread_join(monitor, NULL));
} }
void void
......
...@@ -30,12 +30,18 @@ ...@@ -30,12 +30,18 @@
*/ */
PARENT(SIGTERM, terminate); PARENT(SIGTERM, terminate_action);
PARENT(SIGINT, terminate); PARENT(SIGINT, terminate_action);
PARENT(SIGUSR1, SIG_IGN); PARENT(SIGUSR1, ignore_action);
PARENT(SIGUSR2, SIG_IGN); PARENT(SIGUSR2, ignore_action);
PARENT(SIGABRT, stacktrace_action);
PARENT(SIGSEGV, stacktrace_action);
PARENT(SIGBUS, stacktrace_action);
CHILD(SIGTERM, terminate); CHILD(SIGTERM, terminate_action);
CHILD(SIGINT, terminate); CHILD(SIGINT, terminate_action);
CHILD(SIGUSR1, dump); CHILD(SIGUSR1, dump_action);
CHILD(SIGUSR2, SIG_IGN); CHILD(SIGUSR2, ignore_action);
CHILD(SIGABRT, stacktrace_action);
CHILD(SIGSEGV, stacktrace_action);
CHILD(SIGBUS, stacktrace_action);
...@@ -50,6 +50,11 @@ ...@@ -50,6 +50,11 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/types.h> #include <sys/types.h>
#ifndef HAVE_EXECINFO_H
#include "compat/execinfo.h"
#else
#include <execinfo.h>
#endif
#include "compat/daemon.h" #include "compat/daemon.h"
#include "vsb.h" #include "vsb.h"
...@@ -70,13 +75,16 @@ ...@@ -70,13 +75,16 @@
#define DEFAULT_CONFIG "/etc/trackrdrd.conf" #define DEFAULT_CONFIG "/etc/trackrdrd.conf"
/* XXX: should this be configurable ? */
#define MAX_STACK_DEPTH 100
/* Hack, because we cannot have #ifdef in the macro definition SIGDISP */ /* Hack, because we cannot have #ifdef in the macro definition SIGDISP */
#define _UNDEFINED(SIG) ((#SIG)[0] == 0) #define _UNDEFINED(SIG) ((#SIG)[0] == 0)
#define UNDEFINED(SIG) _UNDEFINED(SIG) #define UNDEFINED(SIG) _UNDEFINED(SIG)
#define SIGDISP(SIG, disp) \ #define SIGDISP(SIG, action) \
do { if (UNDEFINED(SIG)) break; \ do { if (UNDEFINED(SIG)) break; \
if (signal((SIG), (disp)) == SIG_ERR) \ if (sigaction((SIG), (&action), NULL) != 0) \
LOG_Log(LOG_ALERT, \ LOG_Log(LOG_ALERT, \
"Cannot install handler for " #SIG ": %s", \ "Cannot install handler for " #SIG ": %s", \
strerror(errno)); \ strerror(errno)); \
...@@ -86,6 +94,9 @@ static void child_main(struct VSM_data *vd, int endless); ...@@ -86,6 +94,9 @@ static void child_main(struct VSM_data *vd, int endless);
static volatile sig_atomic_t term; static volatile sig_atomic_t term;
static struct sigaction terminate_action, dump_action, ignore_action,
stacktrace_action, default_action;
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
static void static void
...@@ -250,21 +261,54 @@ OSL_Track(void *priv, enum VSL_tag_e tag, unsigned fd, unsigned len, ...@@ -250,21 +261,54 @@ OSL_Track(void *priv, enum VSL_tag_e tag, unsigned fd, unsigned len,
/* Handle for the PID file */ /* Handle for the PID file */
struct vpf_fh *pfh = NULL; struct vpf_fh *pfh = NULL;
static void
stacktrace(int sig)
{
void *buf[MAX_STACK_DEPTH];
int depth, i;
char **strings;
depth = backtrace (buf, MAX_STACK_DEPTH);
LOG_Log(LOG_ALERT, "Received signal %d (%s), stacktrace follows", sig,
strsignal(sig));
if (depth == 0) {
LOG_Log0(LOG_ERR, "Stacktrace empty");
return;
}
strings = backtrace_symbols(buf, depth);
if (strings == NULL) {
LOG_Log0(LOG_ERR, "Cannot retrieve symbols for stacktrace");
return;
}
for (i = 0; i < depth; i++)
LOG_Log(LOG_ERR, "%p: %s", buf[i], strings[i]);
free(strings);
}
static void static void
dump(int sig) dump(int sig)
{ {
(void) sig;
DATA_Dump(); DATA_Dump();
signal(sig, dump);
} }
static void static void
terminate(int sig) terminate(int sig)
{ {
LOG_Log0(LOG_DEBUG, "Signal handler terminate called");
(void) sig; (void) sig;
term = 1; term = 1;
} }
static void
stacktrace_abort(int sig)
{
stacktrace(sig);
AZ(sigaction(SIGABRT, &default_action, NULL));
LOG_Log0(LOG_ALERT, "Aborting");
abort();
}
static void static void
parent_shutdown(int status, pid_t child_pid) parent_shutdown(int status, pid_t child_pid)
{ {
...@@ -325,8 +369,9 @@ parent_main(pid_t child_pid, struct VSM_data *vd, int endless) ...@@ -325,8 +369,9 @@ parent_main(pid_t child_pid, struct VSM_data *vd, int endless)
LOG_Log(LOG_WARNING, "Worker process %d exited with status %d", LOG_Log(LOG_WARNING, "Worker process %d exited with status %d",
child_pid, WEXITSTATUS(status)); child_pid, WEXITSTATUS(status));
if (WIFSIGNALED(status)) if (WIFSIGNALED(status))
LOG_Log(LOG_WARNING, "Worker process %d exited due to signal %d", LOG_Log(LOG_WARNING,
child_pid, WTERMSIG(status)); "Worker process %d exited due to signal %d (%s)",
child_pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
if (config.restarts && restarts > config.restarts) { if (config.restarts && restarts > config.restarts) {
LOG_Log(LOG_ERR, "Too many restarts: %d", restarts); LOG_Log(LOG_ERR, "Too many restarts: %d", restarts);
...@@ -431,6 +476,7 @@ child_main(struct VSM_data *vd, int endless) ...@@ -431,6 +476,7 @@ child_main(struct VSM_data *vd, int endless)
/* Main loop */ /* Main loop */
term = 0; term = 0;
/* XXX: Varnish restart? */ /* XXX: Varnish restart? */
/* XXX: TERM not noticed until request received */
while (VSL_Dispatch(vd, OSL_Track, NULL)) while (VSL_Dispatch(vd, OSL_Track, NULL))
if (term || !endless) if (term || !endless)
break; break;
...@@ -438,6 +484,7 @@ child_main(struct VSM_data *vd, int endless) ...@@ -438,6 +484,7 @@ child_main(struct VSM_data *vd, int endless)
WRK_Halt(); WRK_Halt();
WRK_Shutdown(); WRK_Shutdown();
AZ(MQ_GlobalShutdown()); AZ(MQ_GlobalShutdown());
MON_StatusShutdown(monitor);
LOG_Log0(LOG_INFO, "Worker process exiting"); LOG_Log0(LOG_INFO, "Worker process exiting");
LOG_Close(); LOG_Close();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
...@@ -568,6 +615,19 @@ main(int argc, char * const *argv) ...@@ -568,6 +615,19 @@ main(int argc, char * const *argv)
if (pfh != NULL) if (pfh != NULL)
VPF_Write(pfh); VPF_Write(pfh);
terminate_action.sa_handler = terminate;
AZ(sigemptyset(&terminate_action.sa_mask));
terminate_action.sa_flags &= ~SA_RESTART;
dump_action.sa_handler = dump;
AZ(sigemptyset(&dump_action.sa_mask));
dump_action.sa_flags |= SA_RESTART;
stacktrace_action.sa_handler = stacktrace_abort;
ignore_action.sa_handler = SIG_IGN;
default_action.sa_handler = SIG_DFL;
if (!D_flag) { if (!D_flag) {
child_pid = fork(); child_pid = fork();
switch(child_pid) { switch(child_pid) {
......
...@@ -188,6 +188,7 @@ typedef enum { ...@@ -188,6 +188,7 @@ typedef enum {
} stats_update_t; } stats_update_t;
void *MON_StatusThread(void *arg); void *MON_StatusThread(void *arg);
void MON_StatusShutdown(pthread_t monitor);
void MON_StatsInit(void); void MON_StatsInit(void);
void MON_StatsUpdate(stats_update_t update); void MON_StatsUpdate(stats_update_t update);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment