[gnome-shell] main: use SA_NODEFER to track signals to being able to raise from alarm
- From: Marco Trevisan <marcotrevi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] main: use SA_NODEFER to track signals to being able to raise from alarm
- Date: Tue, 24 Oct 2017 06:19:54 +0000 (UTC)
commit 891bc45e360b70bffbd081d7c992d73647ac5259
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Tue Oct 24 00:28:33 2017 -0500
main: use SA_NODEFER to track signals to being able to raise from alarm
After we receive one of the tracked signals, in case we get stuck inside
the gjs_dumpstack () call, we use an alarm to raise the previously emitted
signal, however without using SA_NODEFER, the raise inside the alarm handler
will be ignored.
To avoid to handle new signals caused by the handler calls, once we get the
first signal, we just ignore them all as they could only lead to dirty traces.
Also, cleaning up a bit the code, and disabling the shell log handler
in dump_gjs_stack_alarm_sigaction since this might lead to a new
gjs_dumpstack () request.
https://bugzilla.gnome.org/show_bug.cgi?id=789237
src/main.c | 38 +++++++++++++++++++++++---------------
1 files changed, 23 insertions(+), 15 deletions(-)
---
diff --git a/src/main.c b/src/main.c
index 214d2a5..934fbd5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -48,6 +48,7 @@ enum {
SHELL_DEBUG_BACKTRACE_SEGFAULTS = 2,
};
static int _shell_debug;
+static gboolean _tracked_signals[NSIG] = { 0 };
static void
shell_dbus_acquire_name (GDBusProxy *bus,
@@ -332,11 +333,11 @@ shut_up (const char *domain,
}
static void
-dump_gjs_stack_alarm_sigaction (int signo,
- siginfo_t *info,
- void *data)
+dump_gjs_stack_alarm_sigaction (int signo)
{
+ g_log_set_default_handler (g_log_default_handler, NULL);
g_warning ("Failed to dump Javascript stack, got stuck");
+ g_log_set_default_handler (default_log_handler, NULL);
raise (caught_signal);
}
@@ -344,16 +345,24 @@ dump_gjs_stack_alarm_sigaction (int signo,
static void
dump_gjs_stack_on_signal_handler (int signo)
{
- /* Waiting at least 5 seconds for the dumpstack, if it fails, we raise the error */
- struct sigaction sa;
+ struct sigaction sa = { 0 };
+ gsize i;
+
+ /* Ignore all the signals starting this point, a part the one we'll raise
+ * (which is implicitly ignored here through SA_RESETHAND), this is needed
+ * not to get this handler being called by other signals that we were
+ * tracking and that might be emitted by code called starting from now.
+ */
+ for (i = 0; i < G_N_ELEMENTS (_tracked_signals); ++i)
+ {
+ if (_tracked_signals[i] && i != signo)
+ signal (i, SIG_IGN);
+ }
+ /* Waiting at least 5 seconds for the dumpstack, if it fails, we raise the error */
caught_signal = signo;
- memset (&sa, 0, sizeof (sigaction));
+ sa.sa_handler = dump_gjs_stack_alarm_sigaction;
sigemptyset (&sa.sa_mask);
-
- sa.sa_flags = SA_SIGINFO;
- sa.sa_sigaction = dump_gjs_stack_alarm_sigaction;
-
sigaction (SIGALRM, &sa, NULL);
alarm (5);
@@ -366,15 +375,14 @@ dump_gjs_stack_on_signal_handler (int signo)
static void
dump_gjs_stack_on_signal (int signo)
{
- struct sigaction sa;
+ struct sigaction sa = { 0 };
- memset (&sa, 0, sizeof (sigaction));
- sigemptyset (&sa.sa_mask);
-
- sa.sa_flags = SA_RESETHAND;
+ sa.sa_flags = SA_RESETHAND | SA_NODEFER;
sa.sa_handler = dump_gjs_stack_on_signal_handler;
+ sigemptyset (&sa.sa_mask);
sigaction (signo, &sa, NULL);
+ _tracked_signals[signo] = TRUE;
}
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]