mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
gmain: Use alternate signal stack if the application provides one
Some applications, toolkits or languages may define an alternative stack to use for traces. This is for example the case of go. So, in case an application defines an alternate signal stack, GLib should use that instead of the default one to receive signals otherwise it may break the application expectations and write where it's not allowed to.
This commit is contained in:
parent
4607dd77a1
commit
137db219a7
@ -5670,6 +5670,9 @@ ref_unix_signal_handler_unlocked (int signum)
|
||||
action.sa_flags = SA_RESTART | SA_NOCLDSTOP;
|
||||
#else
|
||||
action.sa_flags = SA_NOCLDSTOP;
|
||||
#endif
|
||||
#ifdef SA_ONSTACK
|
||||
action.sa_flags |= SA_ONSTACK;
|
||||
#endif
|
||||
sigaction (signum, &action, NULL);
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "glib-unix.h"
|
||||
#include "gstdio.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
@ -507,6 +508,7 @@ on_sig_received_2 (gpointer data)
|
||||
static void
|
||||
test_signal (int signum)
|
||||
{
|
||||
struct sigaction action;
|
||||
GMainLoop *mainloop;
|
||||
int id;
|
||||
|
||||
@ -515,6 +517,17 @@ test_signal (int signum)
|
||||
sig_received = FALSE;
|
||||
sig_counter = 0;
|
||||
g_unix_signal_add (signum, on_sig_received, mainloop);
|
||||
|
||||
g_assert_no_errno (sigaction (signum, NULL, &action));
|
||||
|
||||
g_assert_true (action.sa_flags & SA_NOCLDSTOP);
|
||||
#ifdef SA_RESTART
|
||||
g_assert_true (action.sa_flags & SA_RESTART);
|
||||
#endif
|
||||
#ifdef SA_ONSTACK
|
||||
g_assert_true (action.sa_flags & SA_ONSTACK);
|
||||
#endif
|
||||
|
||||
kill (getpid (), signum);
|
||||
g_assert (!sig_received);
|
||||
id = g_timeout_add (5000, on_sig_timeout, mainloop);
|
||||
@ -554,6 +567,46 @@ test_sigterm (void)
|
||||
test_signal (SIGTERM);
|
||||
}
|
||||
|
||||
static void
|
||||
test_signal_alternate_stack (int signal)
|
||||
{
|
||||
#ifndef SA_ONSTACK
|
||||
g_test_skip ("alternate stack is not supported");
|
||||
#else
|
||||
guint8 stack_memory[MINSIGSTKSZ];
|
||||
guint8 zero_mem[MINSIGSTKSZ];
|
||||
stack_t stack = { .ss_sp = stack_memory, .ss_size = MINSIGSTKSZ };
|
||||
stack_t old_stack = { 0 };
|
||||
|
||||
memset (stack_memory, 0, MINSIGSTKSZ);
|
||||
memset (zero_mem, 0, MINSIGSTKSZ);
|
||||
g_assert_cmpmem (stack_memory, MINSIGSTKSZ, zero_mem, MINSIGSTKSZ);
|
||||
|
||||
g_assert_no_errno (sigaltstack (&stack, &old_stack));
|
||||
|
||||
test_signal (signal);
|
||||
|
||||
/* Very stupid check to ensure that the alternate stack is used instead of
|
||||
* the default one. This test would fail if SA_ONSTACK wouldn't be set.
|
||||
*/
|
||||
g_assert_cmpint (memcmp (stack_memory, zero_mem, MINSIGSTKSZ), !=, 0);
|
||||
|
||||
g_assert_no_errno (sigaltstack (&old_stack, NULL));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
test_sighup_alternate_stack (void)
|
||||
{
|
||||
test_signal_alternate_stack (SIGHUP);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sigterm_alternate_stack (void)
|
||||
{
|
||||
test_signal_alternate_stack (SIGTERM);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sighup_add_remove (void)
|
||||
{
|
||||
@ -807,6 +860,9 @@ main (int argc,
|
||||
g_test_add_func ("/glib-unix/sighup", test_sighup);
|
||||
g_test_add_func ("/glib-unix/sigterm", test_sigterm);
|
||||
g_test_add_func ("/glib-unix/sighup_again", test_sighup);
|
||||
g_test_add_func ("/glib-unix/sighup/alternate-stack", test_sighup_alternate_stack);
|
||||
g_test_add_func ("/glib-unix/sigterm/alternate-stack", test_sigterm_alternate_stack);
|
||||
g_test_add_func ("/glib-unix/sighup_again/alternate-stack", test_sighup_alternate_stack);
|
||||
g_test_add_func ("/glib-unix/sighup_add_remove", test_sighup_add_remove);
|
||||
g_test_add_func ("/glib-unix/sighup_nested", test_sighup_nested);
|
||||
g_test_add_func ("/glib-unix/callback_after_signal", test_callback_after_signal);
|
||||
|
Loading…
Reference in New Issue
Block a user