Blame SOURCES/gdb-rhbz1531838-rhbz1473411-spawn-default-signal-handlers-regression.patch

8f6b9e
commit 1ec6a1148ad3ca06f48be269e1b61cb9c61a0938
8f6b9e
Author: Pedro Alves <palves@redhat.com>
8f6b9e
Date:   Fri Jan 5 18:30:49 2018 +0000
8f6b9e
8f6b9e
    Fix regression: cannot start with LD_PRELOAD=libSegFault.so (PR gdb/18653#c7)
8f6b9e
    
8f6b9e
    At https://sourceware.org/bugzilla/show_bug.cgi?id=18653#c7, Andrew
8f6b9e
    reports that the fix for PR gdb/18653 made GDB useless if you preload
8f6b9e
    libSegFault.so, because GDB internal-errors on startup:
8f6b9e
    
8f6b9e
     $ LD_PRELOAD=libSegFault.so gdb
8f6b9e
     src/gdb/common/signals-state-save-restore.c:64: internal-error: unexpected signal handler
8f6b9e
     A problem internal to GDB has been detected,
8f6b9e
     further debugging may prove unreliable.
8f6b9e
     Aborted (core dumped)
8f6b9e
     $
8f6b9e
    
8f6b9e
    The internal error comes from the code saving the signal dispositions
8f6b9e
    inherited from gdb's parent:
8f6b9e
    
8f6b9e
     (top-gdb) bt
8f6b9e
     #0  0x000000000056b001 in internal_error(char const*, int, char const*, ...) (file=0xaf5f38 "src/gdb/common/signals-state-save-restore.c", line=64, fmt=0xaf5f18 "unexpected signal handler") at src/gdb/common/errors.c:54
8f6b9e
     #1  0x00000000005752c9 in save_original_signals_state() () at src/gdb/common/signals-state-save-restore.c:64
8f6b9e
     #2  0x00000000007425de in captured_main_1(captured_main_args*) (context=0x7fffffffd860)
8f6b9e
         at src/gdb/main.c:509
8f6b9e
     #3  0x0000000000743622 in captured_main(void*) (data=0x7fffffffd860) at src/gdb/main.c:1145
8f6b9e
     During symbol reading, cannot get low and high bounds for subprogram DIE at 24065.
8f6b9e
     #4  0x00000000007436f9 in gdb_main(captured_main_args*) (args=0x7fffffffd860) at src/gdb/main.c:1171
8f6b9e
     #5  0x0000000000413acd in main(int, char**) (argc=1, argv=0x7fffffffd968) at src/gdb/gdb.c:32
8f6b9e
    
8f6b9e
    This commit downgrades the internal error to a warning.  You'll get
8f6b9e
    instead:
8f6b9e
    
8f6b9e
    ~~~
8f6b9e
     $ LD_PRELOAD=libSegFault.so gdb
8f6b9e
     warning: Found custom handler for signal 11 (Segmentation fault) preinstalled.
8f6b9e
     Some signal dispositions inherited from the environment (SIG_DFL/SIG_IGN)
8f6b9e
     won't be propagated to spawned programs.
8f6b9e
     GNU gdb (GDB) 8.0.50.20171213-git
8f6b9e
     Copyright (C) 2017 Free Software Foundation, Inc.
8f6b9e
     License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
8f6b9e
     This is free software: you are free to change and redistribute it.
8f6b9e
     There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
8f6b9e
     and "show warranty" for details.
8f6b9e
     This GDB was configured as "x86_64-pc-linux-gnu".
8f6b9e
     Type "show configuration" for configuration details.
8f6b9e
     For bug reporting instructions, please see:
8f6b9e
     <http://www.gnu.org/software/gdb/bugs/>.
8f6b9e
     Find the GDB manual and other documentation resources online at:
8f6b9e
     <http://www.gnu.org/software/gdb/documentation/>.
8f6b9e
     For help, type "help".
8f6b9e
     Type "apropos word" to search for commands related to "word"...
8f6b9e
     (gdb)
8f6b9e
    ~~~
8f6b9e
    
8f6b9e
    This also moves the location where save_original_signals_state is
8f6b9e
    called a bit further below (to after option processing), so that "-q"
8f6b9e
    disables the warning:
8f6b9e
    
8f6b9e
    ~~~
8f6b9e
     $ LD_PRELOAD=libSegFault.so gdb -q
8f6b9e
     (gdb)
8f6b9e
    ~~~
8f6b9e
    
8f6b9e
    New testcase included.
8f6b9e
    
8f6b9e
    gdb/ChangeLog:
8f6b9e
    2018-01-05  Pedro Alves  <palves@redhat.com>
8f6b9e
    
8f6b9e
            PR gdb/18653
8f6b9e
            * common/signals-state-save-restore.c
8f6b9e
            (save_original_signals_state): New parameter 'quiet'.  Warn if we
8f6b9e
            find a custom handler preinstalled, instead of internal erroring.
8f6b9e
            But only warn if !quiet.
8f6b9e
            * common/signals-state-save-restore.h
8f6b9e
            (save_original_signals_state): New parameter 'quiet'.
8f6b9e
            * main.c (captured_main_1): Move save_original_signals_state call
8f6b9e
            after option handling, and pass QUIET.
8f6b9e
    
8f6b9e
    gdb/gdbserver/ChangeLog:
8f6b9e
    2018-01-05  Pedro Alves  <palves@redhat.com>
8f6b9e
    
8f6b9e
            PR gdb/18653
8f6b9e
            * server.c (captured_main): Pass quiet=false to
8f6b9e
            save_original_signals_state.
8f6b9e
    
8f6b9e
    gdb/testsuite/ChangeLog:
8f6b9e
    2018-01-05  Pedro Alves  <palves@redhat.com>
8f6b9e
    
8f6b9e
            PR gdb/18653
8f6b9e
            * gdb.base/libsegfault.exp: New.
8f6b9e
8f6b9e
### a/gdb/ChangeLog
8f6b9e
### b/gdb/ChangeLog
8f6b9e
## -1,3 +1,15 @@
8f6b9e
+2018-01-05  Pedro Alves  <palves@redhat.com>
8f6b9e
+
8f6b9e
+	PR gdb/18653
8f6b9e
+	* common/signals-state-save-restore.c
8f6b9e
+	(save_original_signals_state): New parameter 'quiet'.  Warn if we
8f6b9e
+	find a custom handler preinstalled, instead of internal erroring.
8f6b9e
+	But only warn if !quiet.
8f6b9e
+	* common/signals-state-save-restore.h
8f6b9e
+	(save_original_signals_state): New parameter 'quiet'.
8f6b9e
+	* main.c (captured_main_1): Move save_original_signals_state call
8f6b9e
+	after option handling, and pass QUIET.
8f6b9e
+
8f6b9e
 2018-01-05  Pedro Alves  <palves@redhat.com>
8f6b9e
 
8f6b9e
 	* spu-tdep.c (spu_catch_start): Pass
8f6b9e
Index: gdb-7.6.1/gdb/common/signals-state-save-restore.c
8f6b9e
===================================================================
8f6b9e
--- gdb-7.6.1.orig/gdb/common/signals-state-save-restore.c	2018-01-08 15:30:48.182057111 +0100
8f6b9e
+++ gdb-7.6.1/gdb/common/signals-state-save-restore.c	2018-01-08 15:37:50.450183830 +0100
8f6b9e
@@ -24,6 +24,7 @@
8f6b9e
 #include "signals-state-save-restore.h"
8f6b9e
 
8f6b9e
 #include <signal.h>
8f6b9e
+#include <string.h>
8f6b9e
 
8f6b9e
 /* The original signal actions and mask.  */
8f6b9e
 
8f6b9e
@@ -40,11 +41,12 @@
8f6b9e
 /* See signals-state-save-restore.h.   */
8f6b9e
 
8f6b9e
 void
8f6b9e
-save_original_signals_state (void)
8f6b9e
+save_original_signals_state (int quiet)
8f6b9e
 {
8f6b9e
 #ifdef HAVE_SIGACTION
8f6b9e
   int i;
8f6b9e
   int res;
8f6b9e
+  int found_preinstalled = 0;
8f6b9e
 
8f6b9e
   res = sigprocmask (0,  NULL, &original_signal_mask);
8f6b9e
   if (res == -1)
8f6b9e
@@ -64,9 +66,31 @@
8f6b9e
 	perror_with_name ("sigaction");
8f6b9e
 
8f6b9e
       /* If we find a custom signal handler already installed, then
8f6b9e
-	 this function was called too late.  */
8f6b9e
-      if (oldact->sa_handler != SIG_DFL && oldact->sa_handler != SIG_IGN)
8f6b9e
-	internal_error (__FILE__, __LINE__, _("unexpected signal handler"));
8f6b9e
+	 this function was called too late.  This is a warning instead
8f6b9e
+	 of an internal error because this can also happen if you
8f6b9e
+	 LD_PRELOAD a library that installs a signal handler early via
8f6b9e
+	 __attribute__((constructor)), like libSegFault.so.  */
8f6b9e
+      if (!quiet
8f6b9e
+	  && oldact->sa_handler != SIG_DFL
8f6b9e
+	  && oldact->sa_handler != SIG_IGN)
8f6b9e
+	{
8f6b9e
+	  found_preinstalled = 1;
8f6b9e
+
8f6b9e
+	  /* Use raw fprintf here because we're being called in early
8f6b9e
+	     startup, because GDB's filtered streams are are
8f6b9e
+	     created.  */
8f6b9e
+	  fprintf (stderr,
8f6b9e
+		   _("warning: Found custom handler for signal "
8f6b9e
+		     "%d (%s) preinstalled.\n"), i,
8f6b9e
+		   strsignal (i));
8f6b9e
+	}
8f6b9e
+    }
8f6b9e
+
8f6b9e
+  if (found_preinstalled)
8f6b9e
+    {
8f6b9e
+      fprintf (stderr, _("\
8f6b9e
+Some signal dispositions inherited from the environment (SIG_DFL/SIG_IGN)\n\
8f6b9e
+won't be propagated to spawned programs.\n"));
8f6b9e
     }
8f6b9e
 #endif
8f6b9e
 }
8f6b9e
Index: gdb-7.6.1/gdb/common/signals-state-save-restore.h
8f6b9e
===================================================================
8f6b9e
--- gdb-7.6.1.orig/gdb/common/signals-state-save-restore.h	2018-01-08 15:30:48.613060301 +0100
8f6b9e
+++ gdb-7.6.1/gdb/common/signals-state-save-restore.h	2018-01-08 15:35:15.538036768 +0100
8f6b9e
@@ -28,9 +28,10 @@
8f6b9e
    back to what was originally inherited from gdb/gdbserver's parent,
8f6b9e
    just before execing the target program to debug.  */
8f6b9e
 
8f6b9e
-/* Save the signal state of all signals.  */
8f6b9e
+/* Save the signal state of all signals.  If !QUIET, warn if we detect
8f6b9e
+   a custom signal handler preinstalled.  */
8f6b9e
 
8f6b9e
-extern void save_original_signals_state (void);
8f6b9e
+extern void save_original_signals_state (int quiet);
8f6b9e
 
8f6b9e
 /* Restore the signal state of all signals.  */
8f6b9e
 
8f6b9e
Index: gdb-7.6.1/gdb/gdbserver/server.c
8f6b9e
===================================================================
8f6b9e
--- gdb-7.6.1.orig/gdb/gdbserver/server.c	2018-01-08 15:30:48.613060301 +0100
8f6b9e
+++ gdb-7.6.1/gdb/gdbserver/server.c	2018-01-08 15:38:02.115270202 +0100
8f6b9e
@@ -2896,7 +2896,7 @@
8f6b9e
       exit (1);
8f6b9e
     }
8f6b9e
 
8f6b9e
-  save_original_signals_state ();
8f6b9e
+  save_original_signals_state (0);
8f6b9e
 
8f6b9e
   /* We need to know whether the remote connection is stdio before
8f6b9e
      starting the inferior.  Inferiors created in this scenario have
8f6b9e
Index: gdb-7.6.1/gdb/main.c
8f6b9e
===================================================================
8f6b9e
--- gdb-7.6.1.orig/gdb/main.c	2018-01-08 15:30:51.951085018 +0100
8f6b9e
+++ gdb-7.6.1/gdb/main.c	2018-01-08 15:31:46.874491703 +0100
8f6b9e
@@ -394,7 +394,6 @@
8f6b9e
   textdomain (PACKAGE);
8f6b9e
 
8f6b9e
   bfd_init ();
8f6b9e
-  save_original_signals_state ();
8f6b9e
 
8f6b9e
   make_cleanup (VEC_cleanup (cmdarg_s), &cmdarg_vec);
8f6b9e
   dirsize = 1;
8f6b9e
@@ -778,6 +777,8 @@
8f6b9e
       quiet = 1;
8f6b9e
   }
8f6b9e
 
8f6b9e
+  save_original_signals_state (quiet);
8f6b9e
+
8f6b9e
   /* Initialize all files.  Give the interpreter a chance to take
8f6b9e
      control of the console via the deprecated_init_ui_hook ().  */
8f6b9e
   gdb_init (gdb_program_name);
8f6b9e
Index: gdb-7.6.1/gdb/testsuite/gdb.base/libsegfault.exp
8f6b9e
===================================================================
8f6b9e
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
8f6b9e
+++ gdb-7.6.1/gdb/testsuite/gdb.base/libsegfault.exp	2018-01-08 15:30:51.951085018 +0100
8f6b9e
@@ -0,0 +1,84 @@
8f6b9e
+# Copyright 2017-2018 Free Software Foundation, Inc.
8f6b9e
+
8f6b9e
+# This program is free software; you can redistribute it and/or modify
8f6b9e
+# it under the terms of the GNU General Public License as published by
8f6b9e
+# the Free Software Foundation; either version 3 of the License, or
8f6b9e
+# (at your option) any later version.
8f6b9e
+#
8f6b9e
+# This program is distributed in the hope that it will be useful,
8f6b9e
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
8f6b9e
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8f6b9e
+# GNU General Public License for more details.
8f6b9e
+#
8f6b9e
+# You should have received a copy of the GNU General Public License
8f6b9e
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
8f6b9e
+
8f6b9e
+# This file is part of the gdb testsuite.
8f6b9e
+
8f6b9e
+# Test that GDB tolerates being started with libSegFault.so preloaded
8f6b9e
+# with LD_PRELOAD, and that GDB warns about a custom SIGSEGV custom
8f6b9e
+# handler.  See PR gdb/18653
8f6b9e
+# <https://sourceware.org/bugzilla/show_bug.cgi?id=18653#c7>.
8f6b9e
+
8f6b9e
+# We cannot expect remote hosts to see environment variables set on
8f6b9e
+# the local machine.
8f6b9e
+if { [is_remote host] } {
8f6b9e
+    unsupported "can't set environment variables on remote host"
8f6b9e
+    return -1
8f6b9e
+}
8f6b9e
+
8f6b9e
+# Spawn GDB with LIB preloaded with LD_PRELOAD.  CMDLINE_OPTS are
8f6b9e
+# command line options passed to GDB.
8f6b9e
+
8f6b9e
+proc gdb_spawn_with_ld_preload {lib cmdline_opts} {
8f6b9e
+    global env
8f6b9e
+
8f6b9e
+    save_vars { env(LD_PRELOAD) } {
8f6b9e
+	if { ![info exists env(LD_PRELOAD) ]
8f6b9e
+	     || $env(LD_PRELOAD) == "" } {
8f6b9e
+	    set env(LD_PRELOAD) "$lib"
8f6b9e
+	} else {
8f6b9e
+	    append env(LD_PRELOAD) ":$lib"
8f6b9e
+	}
8f6b9e
+
8f6b9e
+	gdb_spawn_with_cmdline_opts $cmdline_opts
8f6b9e
+    }
8f6b9e
+}
8f6b9e
+
8f6b9e
+proc test_libsegfault {} {
8f6b9e
+    global gdb_prompt
8f6b9e
+
8f6b9e
+    set libsegfault "libSegFault.so"
8f6b9e
+
8f6b9e
+    # When started normally, if libSegFault.so is preloaded, GDB
8f6b9e
+    # should warn about not being able to propagate the signal
8f6b9e
+    # disposition of SIGSEGV.
8f6b9e
+    gdb_exit
8f6b9e
+    gdb_spawn_with_ld_preload $libsegfault ""
8f6b9e
+
8f6b9e
+    set test "gdb emits custom handler warning"
8f6b9e
+    gdb_test_multiple "" $test {
8f6b9e
+	-re "cannot be preloaded.*\r\n$gdb_prompt $" {
8f6b9e
+	    # Glibc 2.22 outputs:
8f6b9e
+	    # ERROR: ld.so: object 'libSegFault.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
8f6b9e
+	    untested "cannot preload libSegFault.so"
8f6b9e
+	    return
8f6b9e
+	}
8f6b9e
+	-re "Found custom handler.*won't be propagated.*\r\n$gdb_prompt $" {
8f6b9e
+	    pass $test
8f6b9e
+	}
8f6b9e
+    }
8f6b9e
+
8f6b9e
+    # "-q" should disable the warning, though.
8f6b9e
+    gdb_exit
8f6b9e
+    gdb_spawn_with_ld_preload $libsegfault "-q"
8f6b9e
+
8f6b9e
+    set test "quiet suppresses custom handler warning"
8f6b9e
+    gdb_test_multiple "" $test {
8f6b9e
+	-re "^$gdb_prompt $" {
8f6b9e
+	    pass $test
8f6b9e
+	}
8f6b9e
+    }
8f6b9e
+}
8f6b9e
+
8f6b9e
+test_libsegfault