From 21987b9c060033d367abc50c29f786df4c21b10c Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sun, 29 Sep 2019 08:50:15 -0600 Subject: Add RAII class for blocking gdb signals This adds configury support and an RAII class that can be used to temporarily block signals that are used by gdb. (This class is not used in this patch, but it split out for easier review.) The idea of this patch is that these signals should only be delivered to the main thread. So, when creating a background thread, they are temporarily blocked; the blocked state is inherited by the new thread. The sigprocmask man page says: The use of sigprocmask() is unspecified in a multithreaded process; see pthread_sigmask(3). This patch changes gdb to use pthread_sigmask when appropriate, by introducing a convenience define. I've updated gdbserver as well, because I had to touch gdbsupport, and because the threading patches will make it link against the thread library. I chose not to touch the NTO code, because I don't know anything about that platform and because I cannot test it. Finally, this modifies an existing spot in the Guile layer to use the new facility. gdb/ChangeLog 2019-11-26 Tom Tromey * gdbsupport/signals-state-save-restore.c (original_signal_mask): Remove comment. (save_original_signals_state, restore_original_signals_state): Use gdb_sigmask. * linux-nat.c (block_child_signals, restore_child_signals_mask) (_initialize_linux_nat): Use gdb_sigmask. * guile/guile.c (_initialize_guile): Use block_signals. * Makefile.in (HFILES_NO_SRCDIR): Add gdb-sigmask.h. * gdbsupport/gdb-sigmask.h: New file. * event-top.c (async_sigtstp_handler): Use gdb_sigmask. * cp-support.c (gdb_demangle): Use gdb_sigmask. * gdbsupport/common.m4 (GDB_AC_COMMON): Check for pthread_sigmask. * configure, config.in: Rebuild. * gdbsupport/block-signals.h: New file. gdb/gdbserver/ChangeLog 2019-11-26 Tom Tromey * remote-utils.c (block_unblock_async_io): Use gdb_sigmask. * linux-low.c (linux_wait_for_event_filtered, linux_async): Use gdb_sigmask. * configure, config.in: Rebuild. Change-Id: If3f37dc57dd859c226e9e4d79458a0514746e8c6 --- gdb/gdbserver/linux-low.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'gdb/gdbserver/linux-low.c') diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index f34811c..688a395 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -50,6 +50,7 @@ #include "gdbsupport/common-inferior.h" #include "nat/fork-inferior.h" #include "gdbsupport/environ.h" +#include "gdbsupport/gdb-sigmask.h" #include "gdbsupport/scoped_restore.h" #ifndef ELFMAG0 /* Don't include here. If it got included by gdb_proc_service.h @@ -2689,7 +2690,7 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid, /* Make sure SIGCHLD is blocked until the sigsuspend below. Block all signals while here. */ sigfillset (&block_mask); - sigprocmask (SIG_BLOCK, &block_mask, &prev_mask); + gdb_sigmask (SIG_BLOCK, &block_mask, &prev_mask); /* Always pull all events out of the kernel. We'll randomly select an event LWP out of all that have events, to prevent @@ -2775,7 +2776,7 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid, { if (debug_threads) debug_printf ("LLW: exit (no unwaited-for LWP)\n"); - sigprocmask (SIG_SETMASK, &prev_mask, NULL); + gdb_sigmask (SIG_SETMASK, &prev_mask, NULL); return -1; } @@ -2785,7 +2786,7 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid, if (debug_threads) debug_printf ("WNOHANG set, no event found\n"); - sigprocmask (SIG_SETMASK, &prev_mask, NULL); + gdb_sigmask (SIG_SETMASK, &prev_mask, NULL); return 0; } @@ -2794,11 +2795,11 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid, debug_printf ("sigsuspend'ing\n"); sigsuspend (&prev_mask); - sigprocmask (SIG_SETMASK, &prev_mask, NULL); + gdb_sigmask (SIG_SETMASK, &prev_mask, NULL); goto retry; } - sigprocmask (SIG_SETMASK, &prev_mask, NULL); + gdb_sigmask (SIG_SETMASK, &prev_mask, NULL); current_thread = event_thread; @@ -6215,7 +6216,7 @@ linux_async (int enable) sigemptyset (&mask); sigaddset (&mask, SIGCHLD); - sigprocmask (SIG_BLOCK, &mask, NULL); + gdb_sigmask (SIG_BLOCK, &mask, NULL); if (enable) { @@ -6223,7 +6224,7 @@ linux_async (int enable) { linux_event_pipe[0] = -1; linux_event_pipe[1] = -1; - sigprocmask (SIG_UNBLOCK, &mask, NULL); + gdb_sigmask (SIG_UNBLOCK, &mask, NULL); warning ("creating event pipe failed."); return previous; @@ -6249,7 +6250,7 @@ linux_async (int enable) linux_event_pipe[1] = -1; } - sigprocmask (SIG_UNBLOCK, &mask, NULL); + gdb_sigmask (SIG_UNBLOCK, &mask, NULL); } return previous; -- cgit v1.1