dispatcher: fix crash while logging from signal handler

Bug rh#1017884 describes a crash, where dbus_init() failed, which causes
a g_warning(). While writing the warning, a SIGTERM hit, and the
signal_handler() tries to call again g_message().

The logging functions of glib are not reentrant and call abort() when
invoked recursivly. The solution, is to use g_unix_signal_add, which
will dispatch the handler on the mainloop asynchronously.

This bug is not that serious, because the dispatcher was about to
terminate anyway. However, it gets registered as a crash by the system
(ABRT).

https://bugzilla.redhat.com/show_bug.cgi?id=1017884

Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
Thomas Haller 2013-11-18 23:37:58 +01:00
parent fbcabeb7f7
commit 073cc01f52

View file

@ -31,6 +31,7 @@
#include <arpa/inet.h>
#include <glib.h>
#include <glib-unix.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
@ -597,27 +598,15 @@ logging_shutdown (void)
closelog ();
}
static void
signal_handler (int signo)
static gboolean
signal_handler (gpointer user_data)
{
if (signo == SIGINT || signo == SIGTERM) {
g_message ("Caught signal %d, shutting down...", signo);
g_main_loop_quit (loop);
}
}
int signo = GPOINTER_TO_INT (user_data);
static void
setup_signals (void)
{
struct sigaction action;
sigset_t mask;
g_message ("Caught signal %d, shutting down...", signo);
g_main_loop_quit (loop);
sigemptyset (&mask);
action.sa_handler = signal_handler;
action.sa_mask = mask;
action.sa_flags = 0;
sigaction (SIGTERM, &action, NULL);
sigaction (SIGINT, &action, NULL);
return G_SOURCE_REMOVE;
}
int
@ -648,7 +637,8 @@ main (int argc, char **argv)
g_option_context_free (opt_ctx);
g_type_init ();
setup_signals ();
g_unix_signal_add (SIGTERM, signal_handler, GINT_TO_POINTER (SIGTERM));
g_unix_signal_add (SIGINT, signal_handler, GINT_TO_POINTER (SIGINT));
if (!debug)
logging_setup ();