binutils-gdb/gdbsupport/signals-state-save-restore.cc

115 lines
3.0 KiB
C++
Raw Normal View History

/* Copyright (C) 2016-2021 Free Software Foundation, Inc.
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.
2016-08-10 03:16:20 +08:00
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"
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. gdb/ChangeLog 2019-11-26 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-11-26 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
2019-09-29 22:50:15 +08:00
#include "gdbsupport/gdb-sigmask.h"
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.
2016-08-10 03:16:20 +08:00
#include <signal.h>
/* The original signal actions and mask. */
#ifdef HAVE_SIGACTION
static struct sigaction original_signal_actions[NSIG];
static sigset_t original_signal_mask;
#endif
/* See signals-state-save-restore.h. */
void
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-06 02:26:18 +08:00
save_original_signals_state (bool quiet)
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.
2016-08-10 03:16:20 +08:00
{
#ifdef HAVE_SIGACTION
int i;
int res;
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. gdb/ChangeLog 2019-11-26 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-11-26 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
2019-09-29 22:50:15 +08:00
res = gdb_sigmask (0, NULL, &original_signal_mask);
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.
2016-08-10 03:16:20 +08:00
if (res == -1)
perror_with_name (("sigprocmask"));
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.
2016-08-10 03:16:20 +08:00
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-06 02:26:18 +08:00
bool found_preinstalled = false;
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.
2016-08-10 03:16:20 +08:00
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"));
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.
2016-08-10 03:16:20 +08:00
/* If we find a custom signal handler already installed, then
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-06 02:26:18 +08:00
this function was called too late. This is a warning instead
of an internal error because this can also happen if you
LD_PRELOAD a library that installs a signal handler early via
__attribute__((constructor)), like libSegFault.so. */
if (!quiet
&& oldact->sa_handler != SIG_DFL
&& oldact->sa_handler != SIG_IGN)
{
found_preinstalled = true;
/* Use raw fprintf here because we're being called in early
startup, before GDB's filtered streams are created. */
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-06 02:26:18 +08:00
fprintf (stderr,
_("warning: Found custom handler for signal "
"%d (%s) preinstalled.\n"), i,
strsignal (i));
}
}
if (found_preinstalled)
{
fprintf (stderr, _("\
Some signal dispositions inherited from the environment (SIG_DFL/SIG_IGN)\n\
won't be propagated to spawned programs.\n"));
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.
2016-08-10 03:16:20 +08:00
}
#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"));
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.
2016-08-10 03:16:20 +08:00
}
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. gdb/ChangeLog 2019-11-26 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-11-26 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
2019-09-29 22:50:15 +08:00
res = gdb_sigmask (SIG_SETMASK, &original_signal_mask, NULL);
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.
2016-08-10 03:16:20 +08:00
if (res == -1)
perror_with_name (("sigprocmask"));
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.
2016-08-10 03:16:20 +08:00
#endif
}