aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.base/signals-state-child.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2016-08-09 20:16:20 +0100
committerPedro Alves <palves@redhat.com>2016-08-09 20:16:20 +0100
commitf348d89aeccaf3eb613e2f31a823baa64300bf88 (patch)
tree66f0119540539603832d1b3170848b1f9711b43a /gdb/testsuite/gdb.base/signals-state-child.c
parent7cfee229f1eb6e3ee98b63918a5189a330284751 (diff)
downloadgdb-f348d89aeccaf3eb613e2f31a823baa64300bf88.zip
gdb-f348d89aeccaf3eb613e2f31a823baa64300bf88.tar.gz
gdb-f348d89aeccaf3eb613e2f31a823baa64300bf88.tar.bz2
Fix PR gdb/18653: gdb disturbs inferior's inherited signal dispositions
gdb's (or gdbserver's) own signal handling should not interfere with the signal dispositions their spawned children inherit. However, it currently does. For example, some paths in gdb cause SIGPIPE to be set to SIG_IGN, and as consequence, the child starts with SIGPIPE to set to SIG_IGN too, even though gdb was started with SIGPIPE set to SIG_DFL. This is because the exec family of functions does not reset the signal disposition of signals that are set to SIG_IGN: http://pubs.opengroup.org/onlinepubs/7908799/xsh/execve.html Signals set to the default action (SIG_DFL) in the calling process image are set to the default action in the new process image. Signals set to be ignored (SIG_IGN) by the calling process image are set to be ignored by the new process image. Signals set to be caught by the calling process image are set to the default action in the new process image (see <signal.h>). And neither does it reset signal masks or flags. In order to be transparent, when spawning new child processes to debug (with "run", etc.), reset signal actions and mask back to what was originally inherited from gdb/gdbserver's parent, just before execing the target program to debug. gdb/ChangeLog: 2016-08-09 Pedro Alves <palves@redhat.com> PR gdb/18653 * Makefile.in (SFILES): Add common/signals-state-save-restore.c. (HFILES_NO_SRCDIR): Add common/signals-state-save-restore.h. (COMMON_OBS): Add signals-state-save-restore.o. (signals-state-save-restore.o): New rule. * configure: Regenerate. * fork-child.c: Include "signals-state-save-restore.h". (fork_inferior): Call restore_original_signals_state. * main.c: Include "signals-state-save-restore.h". (captured_main): Call save_original_signals_state. * common/common.m4: Add sigaction to AC_CHECK_FUNCS checks. * common/signals-state-save-restore.c: New file. * common/signals-state-save-restore.h: New file. gdb/gdbserver/ChangeLog: 2016-08-09 Pedro Alves <palves@redhat.com> PR gdb/18653 * Makefile.in (OBS): Add signals-state-save-restore.o. (signals-state-save-restore.o): New rule. * config.in: Regenerate. * configure: Regenerate. * linux-low.c: Include "signals-state-save-restore.h". (linux_create_inferior): Call restore_original_signals_state. * server.c: Include "dispositions-save-restore.h". (captured_main): Call save_original_signals_state. gdb/testsuite/ChangeLog: 2016-08-09 Pedro Alves <palves@redhat.com> PR gdb/18653 * gdb.base/signals-state-child.c: New file. * gdb.base/signals-state-child.exp: New file. * gdb.gdb/selftest.exp (do_steps_and_nexts): Add new pattern.
Diffstat (limited to 'gdb/testsuite/gdb.base/signals-state-child.c')
-rw-r--r--gdb/testsuite/gdb.base/signals-state-child.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.base/signals-state-child.c b/gdb/testsuite/gdb.base/signals-state-child.c
new file mode 100644
index 0000000..e11fa93
--- /dev/null
+++ b/gdb/testsuite/gdb.base/signals-state-child.c
@@ -0,0 +1,101 @@
+/* Copyright 2016 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/>. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <assert.h>
+#include <errno.h>
+
+#ifndef OUTPUT_TXT
+# define OUTPUT_TXT "output.txt"
+#endif
+
+static void
+perror_and_exit (const char *s)
+{
+ perror (s);
+ exit (1);
+}
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ FILE *out;
+ sigset_t sigset;
+ int res;
+
+ res = sigprocmask (0, NULL, &sigset);
+ if (res != 0)
+ perror_and_exit ("sigprocmask");
+
+ if (argc > 1)
+ out = stdout;
+ else
+ {
+ out = fopen (OUTPUT_TXT, "w");
+ if (out == NULL)
+ perror_and_exit ("fopen");
+ }
+
+ for (i = 1; i < NSIG; i++)
+ {
+ struct sigaction oldact;
+
+ fprintf (out, "signal %d: ", i);
+
+ res = sigaction (i, NULL, &oldact);
+ if (res == -1 && errno == EINVAL)
+ {
+ /* Some signal numbers in the range are invalid. E.g.,
+ signals 32 and 33 on GNU/Linux. */
+ fprintf (out, "invalid");
+ }
+ else if (res == -1)
+ {
+ perror_and_exit ("sigaction");
+ }
+ else
+ {
+ int m;
+
+ fprintf (out, "sigaction={sa_handler=", i);
+
+ if (oldact.sa_handler == SIG_DFL)
+ fprintf (out, "SIG_DFL");
+ else if (oldact.sa_handler == SIG_IGN)
+ fprintf (out, "SIG_IGN");
+ else
+ abort ();
+
+ fprintf (out, ", sa_mask=");
+ for (m = 1; m < NSIG; m++)
+ fprintf (out, "%c", sigismember (&oldact.sa_mask, m) ? '1' : '0');
+
+ fprintf (out, ", sa_flags=%d", oldact.sa_flags);
+
+ fprintf (out, "}, masked=%d", sigismember (&sigset, i));
+ }
+ fprintf (out, "\n");
+ }
+
+ if (out != stdout)
+ fclose (out);
+
+ return 0;
+}