• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Révision530c45db2477335fa3d2a9f4df636739ededcb96 (tree)
l'heure2019-11-11 02:44:49
AuteurTom Tromey <tom@trom...>
CommiterTom Tromey

Message de Log

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.

2019-10-19 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-10-19 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

Change Summary

Modification

--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,23 @@
11 2019-10-19 Tom Tromey <tom@tromey.com>
22
3+ * gdbsupport/signals-state-save-restore.c (original_signal_mask):
4+ Remove comment.
5+ (save_original_signals_state, restore_original_signals_state): Use
6+ gdb_sigmask.
7+ * linux-nat.c (block_child_signals, restore_child_signals_mask)
8+ (_initialize_linux_nat): Use gdb_sigmask.
9+ * guile/guile.c (_initialize_guile): Use block_signals.
10+ * Makefile.in (HFILES_NO_SRCDIR): Add gdb-sigmask.h.
11+ * gdbsupport/gdb-sigmask.h: New file.
12+ * event-top.c (async_sigtstp_handler): Use gdb_sigmask.
13+ * cp-support.c (gdb_demangle): Use gdb_sigmask.
14+ * gdbsupport/common.m4 (GDB_AC_COMMON): Check for
15+ pthread_sigmask.
16+ * configure, config.in: Rebuild.
17+ * gdbsupport/block-signals.h: New file.
18+
19+2019-10-19 Tom Tromey <tom@tromey.com>
20+
321 * acinclude.m4: Include ax_pthread.m4.
422 * Makefile.in (PTHREAD_CFLAGS, PTHREAD_LIBS): New variables.
523 (INTERNAL_CFLAGS_BASE): Use PTHREAD_CFLAGS.
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1471,6 +1471,7 @@ HFILES_NO_SRCDIR = \
14711471 gdbsupport/fileio.h \
14721472 gdbsupport/format.h \
14731473 gdbsupport/gdb-dlfcn.h \
1474+ gdbsupport/gdb-sigmask.h \
14741475 gdbsupport/gdb_assert.h \
14751476 gdbsupport/gdb_binary_search.h \
14761477 gdbsupport/gdb_tilde_expand.h \
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -342,6 +342,9 @@
342342 /* Have PTHREAD_PRIO_INHERIT. */
343343 #undef HAVE_PTHREAD_PRIO_INHERIT
344344
345+/* Define to 1 if you have the `pthread_sigmask' function. */
346+#undef HAVE_PTHREAD_SIGMASK
347+
345348 /* Define to 1 if you have the `ptrace64' function. */
346349 #undef HAVE_PTRACE64
347350
--- a/gdb/configure
+++ b/gdb/configure
@@ -2520,6 +2520,73 @@ fi
25202520 as_fn_set_status $ac_retval
25212521
25222522 } # ac_fn_cxx_try_link
2523+
2524+# ac_fn_cxx_check_func LINENO FUNC VAR
2525+# ------------------------------------
2526+# Tests whether FUNC exists, setting the cache variable VAR accordingly
2527+ac_fn_cxx_check_func ()
2528+{
2529+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
2530+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
2531+$as_echo_n "checking for $2... " >&6; }
2532+if eval \${$3+:} false; then :
2533+ $as_echo_n "(cached) " >&6
2534+else
2535+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
2536+/* end confdefs.h. */
2537+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
2538+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
2539+#define $2 innocuous_$2
2540+
2541+/* System header to define __stub macros and hopefully few prototypes,
2542+ which can conflict with char $2 (); below.
2543+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
2544+ <limits.h> exists even on freestanding compilers. */
2545+
2546+#ifdef __STDC__
2547+# include <limits.h>
2548+#else
2549+# include <assert.h>
2550+#endif
2551+
2552+#undef $2
2553+
2554+/* Override any GCC internal prototype to avoid an error.
2555+ Use char because int might match the return type of a GCC
2556+ builtin and then its argument prototype would still apply. */
2557+#ifdef __cplusplus
2558+extern "C"
2559+#endif
2560+char $2 ();
2561+/* The GNU C library defines this for functions which it implements
2562+ to always fail with ENOSYS. Some functions are actually named
2563+ something starting with __ and the normal name is an alias. */
2564+#if defined __stub_$2 || defined __stub___$2
2565+choke me
2566+#endif
2567+
2568+int
2569+main ()
2570+{
2571+return $2 ();
2572+ ;
2573+ return 0;
2574+}
2575+_ACEOF
2576+if ac_fn_cxx_try_link "$LINENO"; then :
2577+ eval "$3=yes"
2578+else
2579+ eval "$3=no"
2580+fi
2581+rm -f core conftest.err conftest.$ac_objext \
2582+ conftest$ac_exeext conftest.$ac_ext
2583+fi
2584+eval ac_res=\$$3
2585+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
2586+$as_echo "$ac_res" >&6; }
2587+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
2588+
2589+} # ac_fn_cxx_check_func
25232590 cat >config.log <<_ACEOF
25242591 This file contains any messages produced by compilers while
25252592 running configure, to aid debugging if configure makes a mistake.
@@ -14267,6 +14334,21 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
1426714334 fi
1426814335 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_cxx_std_thread" >&5
1426914336 $as_echo "$gdb_cv_cxx_std_thread" >&6; }
14337+
14338+ # This check must be here, while LIBS includes any necessary
14339+ # threading library.
14340+ for ac_func in pthread_sigmask
14341+do :
14342+ ac_fn_cxx_check_func "$LINENO" "pthread_sigmask" "ac_cv_func_pthread_sigmask"
14343+if test "x$ac_cv_func_pthread_sigmask" = xyes; then :
14344+ cat >>confdefs.h <<_ACEOF
14345+#define HAVE_PTHREAD_SIGMASK 1
14346+_ACEOF
14347+
14348+fi
14349+done
14350+
14351+
1427014352 LIBS="$save_LIBS"
1427114353 CXXFLAGS="$save_CXXFLAGS"
1427214354 fi
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -37,6 +37,7 @@
3737 #include "gdbsupport/gdb_setjmp.h"
3838 #include "safe-ctype.h"
3939 #include "gdbsupport/selftest.h"
40+#include "gdbsupport/gdb-sigmask.h"
4041
4142 #define d_left(dc) (dc)->u.s_binary.left
4243 #define d_right(dc) (dc)->u.s_binary.right
@@ -1573,7 +1574,7 @@ gdb_demangle (const char *name, int options)
15731574 sigset_t segv_sig_set;
15741575 sigemptyset (&segv_sig_set);
15751576 sigaddset (&segv_sig_set, SIGSEGV);
1576- sigprocmask (SIG_UNBLOCK, &segv_sig_set, NULL);
1577+ gdb_sigmask (SIG_UNBLOCK, &segv_sig_set, NULL);
15771578 #endif
15781579
15791580 if (!error_reported)
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -40,6 +40,7 @@
4040 #include "gdbsupport/buffer.h"
4141 #include "ser-event.h"
4242 #include "gdb_select.h"
43+#include "gdbsupport/gdb-sigmask.h"
4344
4445 /* readline include files. */
4546 #include "readline/readline.h"
@@ -1127,7 +1128,7 @@ async_sigtstp_handler (gdb_client_data arg)
11271128 sigset_t zero;
11281129
11291130 sigemptyset (&zero);
1130- sigprocmask (SIG_SETMASK, &zero, 0);
1131+ gdb_sigmask (SIG_SETMASK, &zero, 0);
11311132 }
11321133 #elif HAVE_SIGSETMASK
11331134 sigsetmask (0);
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,12 @@
11 2019-10-19 Tom Tromey <tom@tromey.com>
22
3+ * remote-utils.c (block_unblock_async_io): Use gdb_sigmask.
4+ * linux-low.c (linux_wait_for_event_filtered, linux_async): Use
5+ gdb_sigmask.
6+ * configure, config.in: Rebuild.
7+
8+2019-10-19 Tom Tromey <tom@tromey.com>
9+
310 * Makefile.in (PTHREAD_CFLAGS, PTHREAD_LIBS): New variables.
411 (INTERNAL_CFLAGS_BASE): Use PTHREAD_CFLAGS.
512 (GDBSERVER_LIBS): Use PTHREAD_LIBS.
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -195,6 +195,9 @@
195195 /* Have PTHREAD_PRIO_INHERIT. */
196196 #undef HAVE_PTHREAD_PRIO_INHERIT
197197
198+/* Define to 1 if you have the `pthread_sigmask' function. */
199+#undef HAVE_PTHREAD_SIGMASK
200+
198201 /* Define if the target supports PTRACE_GETFPXREGS for extended register
199202 access. */
200203 #undef HAVE_PTRACE_GETFPXREGS
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -1972,6 +1972,119 @@ $as_echo "$ac_res" >&6; }
19721972
19731973 } # ac_fn_c_check_decl
19741974
1975+# ac_fn_cxx_try_link LINENO
1976+# -------------------------
1977+# Try to link conftest.$ac_ext, and return whether this succeeded.
1978+ac_fn_cxx_try_link ()
1979+{
1980+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
1981+ rm -f conftest.$ac_objext conftest$ac_exeext
1982+ if { { ac_try="$ac_link"
1983+case "(($ac_try" in
1984+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
1985+ *) ac_try_echo=$ac_try;;
1986+esac
1987+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
1988+$as_echo "$ac_try_echo"; } >&5
1989+ (eval "$ac_link") 2>conftest.err
1990+ ac_status=$?
1991+ if test -s conftest.err; then
1992+ grep -v '^ *+' conftest.err >conftest.er1
1993+ cat conftest.er1 >&5
1994+ mv -f conftest.er1 conftest.err
1995+ fi
1996+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
1997+ test $ac_status = 0; } && {
1998+ test -z "$ac_cxx_werror_flag" ||
1999+ test ! -s conftest.err
2000+ } && test -s conftest$ac_exeext && {
2001+ test "$cross_compiling" = yes ||
2002+ test -x conftest$ac_exeext
2003+ }; then :
2004+ ac_retval=0
2005+else
2006+ $as_echo "$as_me: failed program was:" >&5
2007+sed 's/^/| /' conftest.$ac_ext >&5
2008+
2009+ ac_retval=1
2010+fi
2011+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
2012+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
2013+ # interfere with the next link command; also delete a directory that is
2014+ # left behind by Apple's compiler. We do this before executing the actions.
2015+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
2016+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
2017+ as_fn_set_status $ac_retval
2018+
2019+} # ac_fn_cxx_try_link
2020+
2021+# ac_fn_cxx_check_func LINENO FUNC VAR
2022+# ------------------------------------
2023+# Tests whether FUNC exists, setting the cache variable VAR accordingly
2024+ac_fn_cxx_check_func ()
2025+{
2026+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
2027+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
2028+$as_echo_n "checking for $2... " >&6; }
2029+if eval \${$3+:} false; then :
2030+ $as_echo_n "(cached) " >&6
2031+else
2032+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
2033+/* end confdefs.h. */
2034+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
2035+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
2036+#define $2 innocuous_$2
2037+
2038+/* System header to define __stub macros and hopefully few prototypes,
2039+ which can conflict with char $2 (); below.
2040+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
2041+ <limits.h> exists even on freestanding compilers. */
2042+
2043+#ifdef __STDC__
2044+# include <limits.h>
2045+#else
2046+# include <assert.h>
2047+#endif
2048+
2049+#undef $2
2050+
2051+/* Override any GCC internal prototype to avoid an error.
2052+ Use char because int might match the return type of a GCC
2053+ builtin and then its argument prototype would still apply. */
2054+#ifdef __cplusplus
2055+extern "C"
2056+#endif
2057+char $2 ();
2058+/* The GNU C library defines this for functions which it implements
2059+ to always fail with ENOSYS. Some functions are actually named
2060+ something starting with __ and the normal name is an alias. */
2061+#if defined __stub_$2 || defined __stub___$2
2062+choke me
2063+#endif
2064+
2065+int
2066+main ()
2067+{
2068+return $2 ();
2069+ ;
2070+ return 0;
2071+}
2072+_ACEOF
2073+if ac_fn_cxx_try_link "$LINENO"; then :
2074+ eval "$3=yes"
2075+else
2076+ eval "$3=no"
2077+fi
2078+rm -f core conftest.err conftest.$ac_objext \
2079+ conftest$ac_exeext conftest.$ac_ext
2080+fi
2081+eval ac_res=\$$3
2082+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
2083+$as_echo "$ac_res" >&6; }
2084+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
2085+
2086+} # ac_fn_cxx_check_func
2087+
19752088 # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
19762089 # --------------------------------------------
19772090 # Tries to find the compile-time value of EXPR in a program that includes
@@ -7609,6 +7722,21 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
76097722 fi
76107723 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_cxx_std_thread" >&5
76117724 $as_echo "$gdb_cv_cxx_std_thread" >&6; }
7725+
7726+ # This check must be here, while LIBS includes any necessary
7727+ # threading library.
7728+ for ac_func in pthread_sigmask
7729+do :
7730+ ac_fn_cxx_check_func "$LINENO" "pthread_sigmask" "ac_cv_func_pthread_sigmask"
7731+if test "x$ac_cv_func_pthread_sigmask" = xyes; then :
7732+ cat >>confdefs.h <<_ACEOF
7733+#define HAVE_PTHREAD_SIGMASK 1
7734+_ACEOF
7735+
7736+fi
7737+done
7738+
7739+
76127740 LIBS="$save_LIBS"
76137741 CXXFLAGS="$save_CXXFLAGS"
76147742 fi
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -50,6 +50,7 @@
5050 #include "gdbsupport/common-inferior.h"
5151 #include "nat/fork-inferior.h"
5252 #include "gdbsupport/environ.h"
53+#include "gdbsupport/gdb-sigmask.h"
5354 #include "gdbsupport/scoped_restore.h"
5455 #ifndef ELFMAG0
5556 /* Don't include <linux/elf.h> 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,
26892690 /* Make sure SIGCHLD is blocked until the sigsuspend below. Block
26902691 all signals while here. */
26912692 sigfillset (&block_mask);
2692- sigprocmask (SIG_BLOCK, &block_mask, &prev_mask);
2693+ gdb_sigmask (SIG_BLOCK, &block_mask, &prev_mask);
26932694
26942695 /* Always pull all events out of the kernel. We'll randomly select
26952696 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,
27752776 {
27762777 if (debug_threads)
27772778 debug_printf ("LLW: exit (no unwaited-for LWP)\n");
2778- sigprocmask (SIG_SETMASK, &prev_mask, NULL);
2779+ gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
27792780 return -1;
27802781 }
27812782
@@ -2785,7 +2786,7 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
27852786 if (debug_threads)
27862787 debug_printf ("WNOHANG set, no event found\n");
27872788
2788- sigprocmask (SIG_SETMASK, &prev_mask, NULL);
2789+ gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
27892790 return 0;
27902791 }
27912792
@@ -2794,11 +2795,11 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
27942795 debug_printf ("sigsuspend'ing\n");
27952796
27962797 sigsuspend (&prev_mask);
2797- sigprocmask (SIG_SETMASK, &prev_mask, NULL);
2798+ gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
27982799 goto retry;
27992800 }
28002801
2801- sigprocmask (SIG_SETMASK, &prev_mask, NULL);
2802+ gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
28022803
28032804 current_thread = event_thread;
28042805
@@ -6215,7 +6216,7 @@ linux_async (int enable)
62156216 sigemptyset (&mask);
62166217 sigaddset (&mask, SIGCHLD);
62176218
6218- sigprocmask (SIG_BLOCK, &mask, NULL);
6219+ gdb_sigmask (SIG_BLOCK, &mask, NULL);
62196220
62206221 if (enable)
62216222 {
@@ -6223,7 +6224,7 @@ linux_async (int enable)
62236224 {
62246225 linux_event_pipe[0] = -1;
62256226 linux_event_pipe[1] = -1;
6226- sigprocmask (SIG_UNBLOCK, &mask, NULL);
6227+ gdb_sigmask (SIG_UNBLOCK, &mask, NULL);
62276228
62286229 warning ("creating event pipe failed.");
62296230 return previous;
@@ -6249,7 +6250,7 @@ linux_async (int enable)
62496250 linux_event_pipe[1] = -1;
62506251 }
62516252
6252- sigprocmask (SIG_UNBLOCK, &mask, NULL);
6253+ gdb_sigmask (SIG_UNBLOCK, &mask, NULL);
62536254 }
62546255
62556256 return previous;
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -28,6 +28,7 @@
2828 #include "gdbsupport/rsp-low.h"
2929 #include "gdbsupport/netstuff.h"
3030 #include "gdbsupport/filestuff.h"
31+#include "gdbsupport/gdb-sigmask.h"
3132 #include <ctype.h>
3233 #if HAVE_SYS_IOCTL_H
3334 #include <sys/ioctl.h>
@@ -807,7 +808,7 @@ block_unblock_async_io (int block)
807808
808809 sigemptyset (&sigio_set);
809810 sigaddset (&sigio_set, SIGIO);
810- sigprocmask (block ? SIG_BLOCK : SIG_UNBLOCK, &sigio_set, NULL);
811+ gdb_sigmask (block ? SIG_BLOCK : SIG_UNBLOCK, &sigio_set, NULL);
811812 #endif
812813 }
813814
--- /dev/null
+++ b/gdb/gdbsupport/block-signals.h
@@ -0,0 +1,65 @@
1+/* Block signals used by gdb
2+
3+ Copyright (C) 2019 Free Software Foundation, Inc.
4+
5+ This file is part of GDB.
6+
7+ This program is free software; you can redistribute it and/or modify
8+ it under the terms of the GNU General Public License as published by
9+ the Free Software Foundation; either version 3 of the License, or
10+ (at your option) any later version.
11+
12+ This program is distributed in the hope that it will be useful,
13+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ GNU General Public License for more details.
16+
17+ You should have received a copy of the GNU General Public License
18+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
19+
20+#ifndef GDBSUPPORT_BLOCK_SIGNALS_H
21+#define GDBSUPPORT_BLOCK_SIGNALS_H
22+
23+#include <signal.h>
24+
25+namespace gdb
26+{
27+
28+/* This is an RAII class that temporarily blocks the signals needed by
29+ gdb. This can be used before starting a new thread to ensure that
30+ this thread starts with the appropriate signals blocked. */
31+class block_signals
32+{
33+public:
34+ block_signals ()
35+ {
36+#ifdef HAVE_PTHREAD_SIGMASK
37+ sigset_t mask;
38+ sigemptyset (&mask);
39+ sigaddset (&mask, SIGINT);
40+ sigaddset (&mask, SIGCHLD);
41+ sigaddset (&mask, SIGALRM);
42+ sigaddset (&mask, SIGWINCH);
43+ pthread_sigmask (SIG_BLOCK, &mask, &m_old_mask);
44+#endif
45+ }
46+
47+ ~block_signals ()
48+ {
49+#ifdef HAVE_PTHREAD_SIGMASK
50+ pthread_sigmask (SIG_SETMASK, &m_old_mask, nullptr);
51+#endif
52+ }
53+
54+ DISABLE_COPY_AND_ASSIGN (block_signals);
55+
56+private:
57+
58+#ifdef HAVE_PTHREAD_SIGMASK
59+ sigset_t m_old_mask;
60+#endif
61+};
62+
63+}
64+
65+#endif /* GDBSUPPORT_BLOCK_SIGNALS_H */
--- a/gdb/gdbsupport/common.m4
+++ b/gdb/gdbsupport/common.m4
@@ -54,6 +54,11 @@ AC_DEFUN([GDB_AC_COMMON], [
5454 [[std::thread t(callback);]])],
5555 gdb_cv_cxx_std_thread=yes,
5656 gdb_cv_cxx_std_thread=no)])
57+
58+ # This check must be here, while LIBS includes any necessary
59+ # threading library.
60+ AC_CHECK_FUNCS([pthread_sigmask])
61+
5762 LIBS="$save_LIBS"
5863 CXXFLAGS="$save_CXXFLAGS"
5964 fi
--- /dev/null
+++ b/gdb/gdbsupport/gdb-sigmask.h
@@ -0,0 +1,45 @@
1+/* sigprocmask wrapper for gdb
2+
3+ Copyright (C) 2019 Free Software Foundation, Inc.
4+
5+ This file is part of GDB.
6+
7+ This program is free software; you can redistribute it and/or modify
8+ it under the terms of the GNU General Public License as published by
9+ the Free Software Foundation; either version 3 of the License, or
10+ (at your option) any later version.
11+
12+ This program is distributed in the hope that it will be useful,
13+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ GNU General Public License for more details.
16+
17+ You should have received a copy of the GNU General Public License
18+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
19+
20+#ifndef GDBSUPPORT_GDB_SIGMASK_H
21+#define GDBSUPPORT_GDB_SIGMASK_H
22+
23+#include <signal.h>
24+
25+#ifdef HAVE_SIGPROCMASK
26+
27+#ifdef HAVE_PTHREAD_SIGMASK
28+#define gdb_sigmask pthread_sigmask
29+#else
30+#define gdb_sigmask sigprocmask
31+#endif
32+
33+#else /* HAVE_SIGPROCMASK */
34+
35+/* Other code checks HAVE_SIGPROCMASK, but if there happened to be a
36+ system that only had pthread_sigmask, we could still use it with
37+ some extra changes. */
38+#ifdef HAVE_PTHREAD_SIGMASK
39+#error pthead_sigmask available without sigprocmask - please report
40+#endif
41+
42+#endif /* HAVE_SIGPROCMASK */
43+
44+
45+#endif /* GDBSUPPORT_GDB_SIGMASK_H */
--- a/gdb/gdbsupport/signals-state-save-restore.c
+++ b/gdb/gdbsupport/signals-state-save-restore.c
@@ -17,6 +17,7 @@
1717
1818 #include "common-defs.h"
1919 #include "signals-state-save-restore.h"
20+#include "gdbsupport/gdb-sigmask.h"
2021
2122 #include <signal.h>
2223
@@ -25,10 +26,6 @@
2526 #ifdef HAVE_SIGACTION
2627 static struct sigaction original_signal_actions[NSIG];
2728
28-/* Note that we use sigprocmask without worrying about threads because
29- the save/restore functions are called either from main, or after a
30- fork. In both cases, we know the calling process is single
31- threaded. */
3229 static sigset_t original_signal_mask;
3330 #endif
3431
@@ -41,7 +38,7 @@ save_original_signals_state (bool quiet)
4138 int i;
4239 int res;
4340
44- res = sigprocmask (0, NULL, &original_signal_mask);
41+ res = gdb_sigmask (0, NULL, &original_signal_mask);
4542 if (res == -1)
4643 perror_with_name (("sigprocmask"));
4744
@@ -110,7 +107,7 @@ restore_original_signals_state (void)
110107 perror_with_name (("sigaction"));
111108 }
112109
113- res = sigprocmask (SIG_SETMASK, &original_signal_mask, NULL);
110+ res = gdb_sigmask (SIG_SETMASK, &original_signal_mask, NULL);
114111 if (res == -1)
115112 perror_with_name (("sigprocmask"));
116113 #endif
--- a/gdb/guile/guile.c
+++ b/gdb/guile/guile.c
@@ -36,6 +36,7 @@
3636 #include "guile-internal.h"
3737 #endif
3838 #include <signal.h>
39+#include "gdbsupport/block-signals.h"
3940
4041 /* The Guile version we're using.
4142 We *could* use the macros in libguile/version.h but that would preclude
@@ -798,10 +799,6 @@ _initialize_guile (void)
798799
799800 #if HAVE_GUILE
800801 {
801-#ifdef HAVE_SIGPROCMASK
802- sigset_t sigchld_mask, prev_mask;
803-#endif
804-
805802 /* The Python support puts the C side in module "_gdb", leaving the Python
806803 side to define module "gdb" which imports "_gdb". There is evidently no
807804 similar convention in Guile so we skip this. */
@@ -813,25 +810,20 @@ _initialize_guile (void)
813810 scm_set_automatic_finalization_enabled (0);
814811 #endif
815812
816-#ifdef HAVE_SIGPROCMASK
817- /* Before we initialize Guile, block SIGCHLD.
813+ /* Before we initialize Guile, block signals needed by gdb
814+ (especially SIGCHLD).
818815 This is done so that all threads created during Guile initialization
819816 have SIGCHLD blocked. PR 17247.
820817 Really libgc and Guile should do this, but we need to work with
821818 libgc 7.4.x. */
822- sigemptyset (&sigchld_mask);
823- sigaddset (&sigchld_mask, SIGCHLD);
824- sigprocmask (SIG_BLOCK, &sigchld_mask, &prev_mask);
825-#endif
826-
827- /* scm_with_guile is the most portable way to initialize Guile.
828- Plus we need to initialize the Guile support while in Guile mode
829- (e.g., called from within a call to scm_with_guile). */
830- scm_with_guile (call_initialize_gdb_module, NULL);
819+ {
820+ gdb::block_signals blocker;
831821
832-#ifdef HAVE_SIGPROCMASK
833- sigprocmask (SIG_SETMASK, &prev_mask, NULL);
834-#endif
822+ /* scm_with_guile is the most portable way to initialize Guile.
823+ Plus we need to initialize the Guile support while in Guile mode
824+ (e.g., called from within a call to scm_with_guile). */
825+ scm_with_guile (call_initialize_gdb_module, NULL);
826+ }
835827
836828 /* Set Guile's backtrace to match the "set guile print-stack" default.
837829 [N.B. The two settings are still separate.]
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -67,6 +67,7 @@
6767 #include "nat/linux-namespaces.h"
6868 #include "gdbsupport/fileio.h"
6969 #include "gdbsupport/scope-exit.h"
70+#include "gdbsupport/gdb-sigmask.h"
7071
7172 /* This comment documents high-level logic of this file.
7273
@@ -764,7 +765,7 @@ block_child_signals (sigset_t *prev_mask)
764765 if (!sigismember (&blocked_mask, SIGCHLD))
765766 sigaddset (&blocked_mask, SIGCHLD);
766767
767- sigprocmask (SIG_BLOCK, &blocked_mask, prev_mask);
768+ gdb_sigmask (SIG_BLOCK, &blocked_mask, prev_mask);
768769 }
769770
770771 /* Restore child signals mask, previously returned by
@@ -773,7 +774,7 @@ block_child_signals (sigset_t *prev_mask)
773774 static void
774775 restore_child_signals_mask (sigset_t *prev_mask)
775776 {
776- sigprocmask (SIG_SETMASK, prev_mask, NULL);
777+ gdb_sigmask (SIG_SETMASK, prev_mask, NULL);
777778 }
778779
779780 /* Mask of signals to pass directly to the inferior. */
@@ -4564,7 +4565,7 @@ Enables printf debugging output."),
45644565 sigaction (SIGCHLD, &sigchld_action, NULL);
45654566
45664567 /* Make sure we don't block SIGCHLD during a sigsuspend. */
4567- sigprocmask (SIG_SETMASK, NULL, &suspend_mask);
4568+ gdb_sigmask (SIG_SETMASK, NULL, &suspend_mask);
45684569 sigdelset (&suspend_mask, SIGCHLD);
45694570
45704571 sigemptyset (&blocked_mask);