binutils-gdb/gdb/common/signals-state-save-restore.h
Pedro Alves e379cee61f Fix regression: cannot start with LD_PRELOAD=libSegFault.so (PR gdb/18653#c7)
At https://sourceware.org/bugzilla/show_bug.cgi?id=18653#c7, Andrew
reports that the fix for PR gdb/18653 made GDB useless if you preload
libSegFault.so, because GDB internal-errors on startup:

 $ LD_PRELOAD=libSegFault.so gdb
 src/gdb/common/signals-state-save-restore.c:64: internal-error: unexpected signal handler
 A problem internal to GDB has been detected,
 further debugging may prove unreliable.
 Aborted (core dumped)
 $

The internal error comes from the code saving the signal dispositions
inherited from gdb's parent:

 (top-gdb) bt
 #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
 #1  0x00000000005752c9 in save_original_signals_state() () at src/gdb/common/signals-state-save-restore.c:64
 #2  0x00000000007425de in captured_main_1(captured_main_args*) (context=0x7fffffffd860)
     at src/gdb/main.c:509
 #3  0x0000000000743622 in captured_main(void*) (data=0x7fffffffd860) at src/gdb/main.c:1145
 During symbol reading, cannot get low and high bounds for subprogram DIE at 24065.
 #4  0x00000000007436f9 in gdb_main(captured_main_args*) (args=0x7fffffffd860) at src/gdb/main.c:1171
 #5  0x0000000000413acd in main(int, char**) (argc=1, argv=0x7fffffffd968) at src/gdb/gdb.c:32

This commit downgrades the internal error to a warning.  You'll get
instead:

~~~
 $ LD_PRELOAD=libSegFault.so gdb
 warning: Found custom handler for signal 11 (Segmentation fault) preinstalled.
 Some signal dispositions inherited from the environment (SIG_DFL/SIG_IGN)
 won't be propagated to spawned programs.
 GNU gdb (GDB) 8.0.50.20171213-git
 Copyright (C) 2017 Free Software Foundation, Inc.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 This is free software: you are free to change and redistribute it.
 There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
 and "show warranty" for details.
 This GDB was configured as "x86_64-pc-linux-gnu".
 Type "show configuration" for configuration details.
 For bug reporting instructions, please see:
 <http://www.gnu.org/software/gdb/bugs/>.
 Find the GDB manual and other documentation resources online at:
 <http://www.gnu.org/software/gdb/documentation/>.
 For help, type "help".
 Type "apropos word" to search for commands related to "word"...
 (gdb)
~~~

This also moves the location where save_original_signals_state is
called a bit further below (to after option processing), so that "-q"
disables the warning:

~~~
 $ LD_PRELOAD=libSegFault.so gdb -q
 (gdb)
~~~

New testcase included.

gdb/ChangeLog:
2018-01-05  Pedro Alves  <palves@redhat.com>

	PR gdb/18653
	* common/signals-state-save-restore.c
	(save_original_signals_state): New parameter 'quiet'.  Warn if we
	find a custom handler preinstalled, instead of internal erroring.
	But only warn if !quiet.
	* common/signals-state-save-restore.h
	(save_original_signals_state): New parameter 'quiet'.
	* main.c (captured_main_1): Move save_original_signals_state call
	after option handling, and pass QUIET.

gdb/gdbserver/ChangeLog:
2018-01-05  Pedro Alves  <palves@redhat.com>

	PR gdb/18653
	* server.c (captured_main): Pass quiet=false to
	save_original_signals_state.

gdb/testsuite/ChangeLog:
2018-01-05  Pedro Alves  <palves@redhat.com>

	PR gdb/18653
	* gdb.base/libsegfault.exp: New.
2018-01-05 18:26:18 +00:00

41 lines
1.6 KiB
C

/* Copyright (C) 2016-2018 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. If !QUIET, warn if we detect
a custom signal handler preinstalled. */
extern void save_original_signals_state (bool quiet);
/* Restore the signal state of all signals. */
extern void restore_original_signals_state (void);
#endif /* COMMON_SIGNALS_STATE_SAVE_RESTORE_H */