summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Vlad <marius.vlad@collabora.com>2022-09-21 17:29:39 +0300
committerMarius Vlad <marius.vlad@collabora.com>2022-09-23 18:15:11 +0300
commit897449688a9c7f934d45acd1eaa09d766d6da67a (patch)
treeeca05f5812ced7baa8cb18e8296f8c917dffe391
parente8761762fcd03d3f561c0a0b761d609ded41c8c3 (diff)
compositor: Use sigaction to trap SIGINT
signalfd interacts badly with gdb's signal trapping - when hitting ctrl-c in a debugger attached to weston, weston will receive the signal. This results in weston exiting cleanly when the intent was to use gdb to interfere with its operation. Trapping SIGINT was introduced in commit 50dc6989 which ensured we would call wl_display_terminate() on SIGINT or SIGTERM to clean up our socket. Killing weston with SIGINT is quite common for several developers, so it's important to preserve this clean shutdown behaviour, so we can't naively stop trapping SIGINT entirely. Instead, use the sigaction() function to trap SIGINT, and have the SIGINT handler send weston SIGUSR2 (SIGUSR1 is already used by xwayland). SIGUSR2 can be trapped in the proper wayland way via wl_event_loop_add_signal(). This way we can properly break our event loop and clean up on SIGINT, but we can also have gdb intercept SIGINT. There are other ways around this, but I'm hoping this one allows people to continue using ctrl-c to stop weston, and doesn't require additional project specific gdb knowledge. Bug-AGL: SPEC-4570 Signed-off-by: Derek Foreman <derek.foreman@collabora.com> Signed-off-by: Marius Vlad <marius.vlad@collabora.com> Change-Id: I42fc186296856861c8b6aee54a302c7c0574a88d
-rw-r--r--src/compositor.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/compositor.c b/src/compositor.c
index add78af..564153b 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -74,6 +74,12 @@ to_ivi_compositor(struct weston_compositor *ec)
}
static void
+sigint_helper(int sig)
+{
+ raise(SIGUSR2);
+}
+
+static void
handle_output_destroy(struct wl_listener *listener, void *data)
{
struct ivi_output *output;
@@ -1625,6 +1631,7 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da
struct weston_log_subscriber *logger;
int ret = EXIT_FAILURE;
bool xwayland = false;
+ struct sigaction action;
const struct weston_option core_options[] = {
{ WESTON_OPTION_STRING, "backend", 'B', &backend },
@@ -1707,11 +1714,26 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da
signals[0] = wl_event_loop_add_signal(loop, SIGTERM, on_term_signal,
display);
- signals[1] = wl_event_loop_add_signal(loop, SIGINT, on_term_signal,
+ signals[1] = wl_event_loop_add_signal(loop, SIGUSR2, on_term_signal,
display);
signals[2] = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
display);
+ /* When debugging the compositor, if use wl_event_loop_add_signal() to
+ * catch SIGINT, the debugger can't catch it, and attempting to stop
+ * the compositor from within the debugger results in weston exiting
+ * cleanly.
+ *
+ * Instead, use the sigaction() function, which sets up the signal in a
+ * way that gdb can successfully catch, but have the handler for SIGINT
+ * send SIGUSR2 (xwayland uses SIGUSR1), which we catch via
+ * wl_event_loop_add_signal().
+ */
+ action.sa_handler = sigint_helper;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ sigaction(SIGINT, &action, NULL);
+
for (size_t i = 0; i < ARRAY_LENGTH(signals); ++i)
if (!signals[i])
goto error_signals;