aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbsupport
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2019-09-29 08:50:15 -0600
committerTom Tromey <tom@tromey.com>2019-11-26 14:02:57 -0700
commit21987b9c060033d367abc50c29f786df4c21b10c (patch)
tree6071a96c314722b150c9a228478d594ed11c68b0 /gdb/gdbsupport
parent5e03027845ecc877621ea71bc342a30ecf2999ff (diff)
downloadgdb-21987b9c060033d367abc50c29f786df4c21b10c.zip
gdb-21987b9c060033d367abc50c29f786df4c21b10c.tar.gz
gdb-21987b9c060033d367abc50c29f786df4c21b10c.tar.bz2
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 <tom@tromey.com> * 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 <tom@tromey.com> * 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
Diffstat (limited to 'gdb/gdbsupport')
-rw-r--r--gdb/gdbsupport/block-signals.h67
-rw-r--r--gdb/gdbsupport/common.m45
-rw-r--r--gdb/gdbsupport/gdb-sigmask.h45
-rw-r--r--gdb/gdbsupport/signals-state-save-restore.c9
4 files changed, 120 insertions, 6 deletions
diff --git a/gdb/gdbsupport/block-signals.h b/gdb/gdbsupport/block-signals.h
new file mode 100644
index 0000000..3f11aba
--- /dev/null
+++ b/gdb/gdbsupport/block-signals.h
@@ -0,0 +1,67 @@
+/* Block signals used by gdb
+
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDBSUPPORT_BLOCK_SIGNALS_H
+#define GDBSUPPORT_BLOCK_SIGNALS_H
+
+#include <signal.h>
+
+#include "gdbsupport/gdb-sigmask.h"
+
+namespace gdb
+{
+
+/* This is an RAII class that temporarily blocks the signals needed by
+ gdb. This can be used before starting a new thread to ensure that
+ this thread starts with the appropriate signals blocked. */
+class block_signals
+{
+public:
+ block_signals ()
+ {
+#ifdef HAVE_SIGPROCMASK
+ sigset_t mask;
+ sigemptyset (&mask);
+ sigaddset (&mask, SIGINT);
+ sigaddset (&mask, SIGCHLD);
+ sigaddset (&mask, SIGALRM);
+ sigaddset (&mask, SIGWINCH);
+ gdb_sigmask (SIG_BLOCK, &mask, &m_old_mask);
+#endif
+ }
+
+ ~block_signals ()
+ {
+#ifdef HAVE_SIGPROCMASK
+ gdb_sigmask (SIG_SETMASK, &m_old_mask, nullptr);
+#endif
+ }
+
+ DISABLE_COPY_AND_ASSIGN (block_signals);
+
+private:
+
+#ifdef HAVE_SIGPROCMASK
+ sigset_t m_old_mask;
+#endif
+};
+
+}
+
+#endif /* GDBSUPPORT_BLOCK_SIGNALS_H */
diff --git a/gdb/gdbsupport/common.m4 b/gdb/gdbsupport/common.m4
index f813c04..e993b20 100644
--- a/gdb/gdbsupport/common.m4
+++ b/gdb/gdbsupport/common.m4
@@ -54,6 +54,11 @@ AC_DEFUN([GDB_AC_COMMON], [
[[std::thread t(callback);]])],
gdb_cv_cxx_std_thread=yes,
gdb_cv_cxx_std_thread=no)])
+
+ # This check must be here, while LIBS includes any necessary
+ # threading library.
+ AC_CHECK_FUNCS([pthread_sigmask])
+
LIBS="$save_LIBS"
CXXFLAGS="$save_CXXFLAGS"
fi
diff --git a/gdb/gdbsupport/gdb-sigmask.h b/gdb/gdbsupport/gdb-sigmask.h
new file mode 100644
index 0000000..08ad973
--- /dev/null
+++ b/gdb/gdbsupport/gdb-sigmask.h
@@ -0,0 +1,45 @@
+/* sigprocmask wrapper for gdb
+
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDBSUPPORT_GDB_SIGMASK_H
+#define GDBSUPPORT_GDB_SIGMASK_H
+
+#include <signal.h>
+
+#ifdef HAVE_SIGPROCMASK
+
+#ifdef HAVE_PTHREAD_SIGMASK
+#define gdb_sigmask pthread_sigmask
+#else
+#define gdb_sigmask sigprocmask
+#endif
+
+#else /* HAVE_SIGPROCMASK */
+
+/* Other code checks HAVE_SIGPROCMASK, but if there happened to be a
+ system that only had pthread_sigmask, we could still use it with
+ some extra changes. */
+#ifdef HAVE_PTHREAD_SIGMASK
+#error pthead_sigmask available without sigprocmask - please report
+#endif
+
+#endif /* HAVE_SIGPROCMASK */
+
+
+#endif /* GDBSUPPORT_GDB_SIGMASK_H */
diff --git a/gdb/gdbsupport/signals-state-save-restore.c b/gdb/gdbsupport/signals-state-save-restore.c
index c66d2dd..25a8220 100644
--- a/gdb/gdbsupport/signals-state-save-restore.c
+++ b/gdb/gdbsupport/signals-state-save-restore.c
@@ -17,6 +17,7 @@
#include "common-defs.h"
#include "signals-state-save-restore.h"
+#include "gdbsupport/gdb-sigmask.h"
#include <signal.h>
@@ -25,10 +26,6 @@
#ifdef HAVE_SIGACTION
static struct sigaction original_signal_actions[NSIG];
-/* Note that we use sigprocmask without worrying about threads because
- the save/restore functions are called either from main, or after a
- fork. In both cases, we know the calling process is single
- threaded. */
static sigset_t original_signal_mask;
#endif
@@ -41,7 +38,7 @@ save_original_signals_state (bool quiet)
int i;
int res;
- res = sigprocmask (0, NULL, &original_signal_mask);
+ res = gdb_sigmask (0, NULL, &original_signal_mask);
if (res == -1)
perror_with_name (("sigprocmask"));
@@ -110,7 +107,7 @@ restore_original_signals_state (void)
perror_with_name (("sigaction"));
}
- res = sigprocmask (SIG_SETMASK, &original_signal_mask, NULL);
+ res = gdb_sigmask (SIG_SETMASK, &original_signal_mask, NULL);
if (res == -1)
perror_with_name (("sigprocmask"));
#endif