Fix PR gdb/18653: gdb disturbs inferior's inherited signal dispositions
authorPedro Alves <palves@redhat.com>
Tue, 9 Aug 2016 19:16:20 +0000 (20:16 +0100)
committerPedro Alves <palves@redhat.com>
Tue, 9 Aug 2016 19:16:20 +0000 (20:16 +0100)
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.

18 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/common/common.m4
gdb/common/signals-state-save-restore.c [new file with mode: 0644]
gdb/common/signals-state-save-restore.h [new file with mode: 0644]
gdb/configure
gdb/fork-child.c
gdb/gdbserver/ChangeLog
gdb/gdbserver/Makefile.in
gdb/gdbserver/config.in
gdb/gdbserver/configure
gdb/gdbserver/linux-low.c
gdb/gdbserver/server.c
gdb/main.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/signals-state-child.c [new file with mode: 0644]
gdb/testsuite/gdb.base/signals-state-child.exp [new file with mode: 0644]
gdb/testsuite/gdb.gdb/selftest.exp

index dd874209e770192b44e3e726da615170cd69d20e..bfa131fa3c971d0a942694f9ac602222ad445083 100644 (file)
@@ -1,3 +1,20 @@
+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.
+
 2016-08-09  Pedro Alves  <palves@redhat.com>
 
        * value.c (unpack_value_bitfield): Skip unpacking if the parent
index 5af61036e8e9e1119ddf6ef24259ae9d8a76bd21..7b2df86878fd790857612e778afb44a1eba56be8 100644 (file)
@@ -897,6 +897,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
        target/waitstatus.c common/print-utils.c common/rsp-low.c \
        common/errors.c common/common-debug.c common/common-exceptions.c \
        common/btrace-common.c common/fileio.c common/common-regcache.c \
+       common/signals-state-save-restore.c \
        $(SUBDIR_GCC_COMPILE_SRCS)
 
 LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
@@ -989,7 +990,8 @@ common/common-exceptions.h target/target.h common/symbol.h \
 common/common-regcache.h fbsd-tdep.h nat/linux-personality.h \
 common/fileio.h nat/x86-linux.h nat/x86-linux-dregs.h nat/amd64-linux-siginfo.h\
 nat/linux-namespaces.h arch/arm.h common/gdb_sys_time.h arch/aarch64-insn.h \
-tid-parse.h ser-event.h
+tid-parse.h ser-event.h \
+common/signals-state-save-restore.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -1049,6 +1051,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
        build-id.o buildsym.o \
        findcmd.o \
        std-regs.o \
+       signals-state-save-restore.o \
        signals.o \
        exec.o reverse.o \
        bcache.o objfiles.o observer.o minsyms.o maint.o demangle.o \
@@ -2286,6 +2289,10 @@ common-regcache.o: ${srcdir}/common/common-regcache.c
        $(COMPILE) $(srcdir)/common/common-regcache.c
        $(POSTCOMPILE)
 
+signals-state-save-restore.o: $(srcdir)/common/signals-state-save-restore.c
+       $(COMPILE) $(srcdir)/common/signals-state-save-restore.c
+       $(POSTCOMPILE)
+
 #
 # gdb/target/ dependencies
 #
index 1342503aaf4fc4d1b524ad59431dd961e70d35d0..68afc65ba27ca4cf674e4c91951dae8587245c8f 100644 (file)
@@ -30,7 +30,7 @@ AC_DEFUN([GDB_AC_COMMON], [
                   sys/un.h sys/wait.h dnl
                   thread_db.h wait.h)
 
-  AC_CHECK_FUNCS([fdwalk getrlimit pipe pipe2 socketpair])
+  AC_CHECK_FUNCS([fdwalk getrlimit pipe pipe2 socketpair sigaction])
 
   AC_CHECK_DECLS([strerror, strstr])
 
diff --git a/gdb/common/signals-state-save-restore.c b/gdb/common/signals-state-save-restore.c
new file mode 100644 (file)
index 0000000..1c00cdd
--- /dev/null
@@ -0,0 +1,94 @@
+/* Copyright (C) 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 "common-defs.h"
+#include "signals-state-save-restore.h"
+
+#include <signal.h>
+
+/* The original signal actions and mask.  */
+
+#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
+
+/* See signals-state-save-restore.h.   */
+
+void
+save_original_signals_state (void)
+{
+#ifdef HAVE_SIGACTION
+  int i;
+  int res;
+
+  res = sigprocmask (0,  NULL, &original_signal_mask);
+  if (res == -1)
+    perror_with_name ("sigprocmask");
+
+  for (i = 1; i < NSIG; i++)
+    {
+      struct sigaction *oldact = &original_signal_actions[i];
+
+      res = sigaction (i, NULL, oldact);
+      if (res == -1 && errno == EINVAL)
+       {
+         /* Some signal numbers in the range are invalid.  */
+         continue;
+       }
+      else if (res == -1)
+       perror_with_name ("sigaction");
+
+      /* If we find a custom signal handler already installed, then
+        this function was called too late.  */
+      if (oldact->sa_handler != SIG_DFL && oldact->sa_handler != SIG_IGN)
+       internal_error (__FILE__, __LINE__, _("unexpected signal handler"));
+    }
+#endif
+}
+
+/* See signals-state-save-restore.h.   */
+
+void
+restore_original_signals_state (void)
+{
+#ifdef HAVE_SIGACTION
+  int i;
+  int res;
+
+  for (i = 1; i < NSIG; i++)
+    {
+      res = sigaction (i, &original_signal_actions[i], NULL);
+      if (res == -1 && errno == EINVAL)
+       {
+         /* Some signal numbers in the range are invalid.  */
+         continue;
+       }
+      else if (res == -1)
+       perror_with_name ("sigaction");
+    }
+
+  res = sigprocmask (SIG_SETMASK,  &original_signal_mask, NULL);
+  if (res == -1)
+    perror_with_name ("sigprocmask");
+#endif
+}
diff --git a/gdb/common/signals-state-save-restore.h b/gdb/common/signals-state-save-restore.h
new file mode 100644 (file)
index 0000000..bed77fe
--- /dev/null
@@ -0,0 +1,39 @@
+/* Copyright (C) 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/>.  */
+
+#ifndef COMMON_SIGNALS_STATE_SAVE_RESTORE_H
+#define COMMON_SIGNALS_STATE_SAVE_RESTORE_H
+
+/* Save/restore the signal actions of all signals, and the signal
+   mask.
+
+   Since the exec family of functions does not reset the signal
+   disposition of signals set to SIG_IGN, nor does it reset the signal
+   mask, in order to be transparent, when spawning new child processes
+   to debug (with "run", etc.), we must reset signal actions and mask
+   back to what was originally inherited from gdb/gdbserver's parent,
+   just before execing the target program to debug.  */
+
+/* Save the signal state of all signals.  */
+
+extern void save_original_signals_state (void);
+
+/* Restore the signal state of all signals.  */
+
+extern void restore_original_signals_state (void);
+
+#endif /* COMMON_SIGNALS_STATE_SAVE_RESTORE_H */
index 8f92ed92c3a4b704bd0817e2c9a3c88a2acc2b78..7577ba4c79806c5f5d089d796dd9d5fd848a49fa 100755 (executable)
@@ -12244,7 +12244,7 @@ fi
 done
 
 
-  for ac_func in fdwalk getrlimit pipe pipe2 socketpair
+  for ac_func in fdwalk getrlimit pipe pipe2 socketpair sigaction
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
index 8ac3befd78ba70f2d45eab97a67f96b74929f77f..6856cf630f58215dc7aee14d6696c4f8e44cf68c 100644 (file)
@@ -32,7 +32,7 @@
 #include "solib.h"
 #include "filestuff.h"
 #include "top.h"
-
+#include "signals-state-save-restore.h"
 #include <signal.h>
 
 /* This just gets used as a default if we can't find SHELL.  */
@@ -366,6 +366,8 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env,
         saying "not parent".  Sorry; you'll have to use print
         statements!  */
 
+      restore_original_signals_state ();
+
       /* There is no execlpe call, so we have to set the environment
          for our child in the global variable.  If we've vforked, this
          clobbers the parent, but environ is restored a few lines down
index e88b001fdf631898fc8f85b0d18481d1ce3d9e1b..69867147b91cb8c6ca3ef9ca2db895d70346a81c 100644 (file)
@@ -1,3 +1,16 @@
+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.
+
 2016-08-05  Pedro Alves  <palves@redhat.com>
 
        * configure: Regenerate.
index 2be61eff4af88ebf3b4b68481c9bd0f9fc99f796..bed2b1e4404d963e72b4c80b3cce8d6ca9666d6c 100644 (file)
@@ -200,6 +200,7 @@ OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o \
       common-utils.o ptid.o buffer.o format.o filestuff.o dll.o notif.o \
       tdesc.o print-utils.o rsp-low.o errors.o common-debug.o cleanups.o \
       common-exceptions.o symbol.o btrace-common.o fileio.o common-regcache.o \
+      signals-state-save-restore.o \
       $(XML_BUILTIN) $(DEPFILES) $(LIBOBJS)
 GDBREPLAY_OBS = gdbreplay.o version.o
 GDBSERVER_LIBS = @GDBSERVER_LIBS@
@@ -715,6 +716,9 @@ fileio.o: ../common/fileio.c
 common-regcache.o: ../common/common-regcache.c
        $(COMPILE) $<
        $(POSTCOMPILE)
+signals-state-save-restore.o: ../common/signals-state-save-restore.c
+       $(COMPILE) $<
+       $(POSTCOMPILE)
 
 # Arch object files rules form ../arch
 
index 2c3a69a2c615b2c1866d74bbb3f2619485473eca..04072cf56b79c9fb6b1969b4b0e493a991ec6278 100644 (file)
 /* Define to 1 if you have the <sgtty.h> header file. */
 #undef HAVE_SGTTY_H
 
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
 /* Define to 1 if you have the <signal.h> header file. */
 #undef HAVE_SIGNAL_H
 
index 80fa1f3d1f3aedb4cfdff9da5bc950ec877e051d..889e35b9ae221792e12cc47c8f84bd24fa3241c2 100755 (executable)
@@ -5913,7 +5913,7 @@ fi
 done
 
 
-  for ac_func in fdwalk getrlimit pipe pipe2 socketpair
+  for ac_func in fdwalk getrlimit pipe pipe2 socketpair sigaction
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
index 1839f998aff2d34e20eddfd5785c50d823650374..45061ac2566880e11c1d4e6621765efa18b79e1e 100644 (file)
@@ -22,7 +22,7 @@
 #include "agent.h"
 #include "tdesc.h"
 #include "rsp-low.h"
-
+#include "signals-state-save-restore.h"
 #include "nat/linux-nat.h"
 #include "nat/linux-waitpid.h"
 #include "gdb_wait.h"
@@ -975,6 +975,8 @@ linux_create_inferior (char *program, char **allargs)
            }
        }
 
+      restore_original_signals_state ();
+
       execv (program, allargs);
       if (errno == ENOENT)
        execvp (program, allargs);
index 6d6cb0923e83c4a6dd374fa3d40a272964abccba..6fbd61db5b51b7ff9c4d83c26c13688093faa55f 100644 (file)
@@ -22,7 +22,7 @@
 #include "notif.h"
 #include "tdesc.h"
 #include "rsp-low.h"
-
+#include "signals-state-save-restore.h"
 #include <ctype.h>
 #include <unistd.h>
 #if HAVE_SIGNAL_H
@@ -3611,6 +3611,8 @@ captured_main (int argc, char *argv[])
      opened by remote_prepare.  */
   notice_open_fds ();
 
+  save_original_signals_state ();
+
   /* We need to know whether the remote connection is stdio before
      starting the inferior.  Inferiors created in this scenario have
      stdin,stdout redirected.  So do this here before we call
index 5477379b249388ffa3db0e84743303a36cb9220d..23d4ca046ae68cc98ecd494e6f83c61718237706 100644 (file)
@@ -44,6 +44,7 @@
 #include <signal.h>
 #include "event-top.h"
 #include "infrun.h"
+#include "signals-state-save-restore.h"
 
 /* The selected interpreter.  This will be used as a set command
    variable, so it should always be malloc'ed - since
@@ -505,6 +506,7 @@ captured_main (void *data)
 
   bfd_init ();
   notice_open_fds ();
+  save_original_signals_state ();
 
   make_cleanup (VEC_cleanup (cmdarg_s), &cmdarg_vec);
   dirsize = 1;
index 4b700591bf08e9f6750f82bd8249639017e0fe58..65815568b7fbf293f334f62349e3a2cdeda1db2b 100644 (file)
@@ -1,3 +1,10 @@
+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.
+
 2016-08-09  Pedro Alves  <palves@redhat.com>
 
        * gdb.dwarf2/bitfield-parent-optimized-out.exp: New file.
diff --git a/gdb/testsuite/gdb.base/signals-state-child.c b/gdb/testsuite/gdb.base/signals-state-child.c
new file mode 100644 (file)
index 0000000..e11fa93
--- /dev/null
@@ -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;
+}
diff --git a/gdb/testsuite/gdb.base/signals-state-child.exp b/gdb/testsuite/gdb.base/signals-state-child.exp
new file mode 100644 (file)
index 0000000..f5fdcb2
--- /dev/null
@@ -0,0 +1,82 @@
+# Copyright 2016 Free Software Foundation, Inc.
+
+# 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/>.
+
+# Test that gdb's (or gdbserver's) own signal handling does not
+# interfere with the signal actions (dispositions, etc.) and mask
+# their spawned children inherit.
+#
+# - If gdb inherits some signal set to SIG_IGN, so should the
+#   inferior, even if gdb itself chooses not to ignore the signal.
+#
+# - If gdb inherits some signal set to SIG_DFL, so should the inferior
+#   even if gdb itself ignores that signal.
+#
+# This requires special support in gdb/gdbserver because the exec
+# family of functions does not reset the signal disposition of signals
+# that are set to SIG_IGN, nor signal masks and flags.
+
+standard_testfile
+
+set gdb_txt [standard_output_file gdb.txt]
+set standalone_txt [standard_output_file standalone.txt]
+remote_exec host "rm -f $gdb_txt"
+remote_exec host "rm -f $standalone_txt"
+
+set options [list debug "additional_flags=-DOUTPUT_TXT=\"$gdb_txt\""]
+if {[build_executable $testfile.exp $testfile $srcfile $options]} {
+    untested $testfile.exp
+    return -1
+}
+
+set options [list debug "additional_flags=-DOUTPUT_TXT=\"$standalone_txt\""]
+if {[build_executable $testfile.exp $testfile-standalone $srcfile $options]} {
+    untested $testfile.exp
+    return -1
+}
+
+# Run the program directly, and dump its initial signal actions and
+# mask in "standalone.txt".
+
+# Use remote_spawn instead of remote_exec, like how we spawn gdb.
+# This is in order to take the same code code paths in dejagnu
+# compared to when running the program through gdb.  E.g., because
+# local_exec uses -ignore SIGHUP, while remote_spawn does not, if we
+# used remote_exec, the test program would start with SIGHUP ignored
+# when run standalone, but not when run through gdb.
+set res [remote_spawn host "$binfile-standalone"]
+if { $res < 0 || $res == "" } {
+    untested "spawning $binfile-standalone failed"
+    return 1
+} else {
+    pass "collect standalone signals state"
+}
+remote_close host
+
+# Now run the program through gdb, and dump its initial signal actions
+# and mask in "gdb.txt".
+
+clean_restart $binfile
+
+if { ! [ runto_main ] } then {
+    untested $testfile.exp
+    return -1
+}
+
+gdb_continue_to_end "collect signals state under gdb"
+
+# Diff the .txt files.  They should be identical.
+gdb_test "shell diff -s $standalone_txt $gdb_txt" \
+    "Files .* are identical.*" \
+    "signals states are identical"
index 2fdd9e3539fae673553c4729ef0f11953858d6f3..28d54930bc9d699b938134684cf42b72fe71e19a 100644 (file)
@@ -162,6 +162,10 @@ proc do_steps_and_nexts {} {
                set description "next over notice_open_fds"
                set command "next"
            }
+           -re ".*save_original_signals_state ..;.*$gdb_prompt $" {
+               set description "next over save_original_signals_state"
+               set command "next"
+           }
            -re ".*VEC_cleanup .cmdarg_s.*$gdb_prompt $" {
                set description "next over cmdarg_s VEC_cleanup"
                set command "next"