
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
114 lines
3 KiB
C
114 lines
3 KiB
C
/* Copyright (C) 2016-2019 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 "gdbsupport/gdb-sigmask.h"
|
|
|
|
#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
|
|
save_original_signals_state (bool quiet)
|
|
{
|
|
#ifdef HAVE_SIGACTION
|
|
int i;
|
|
int res;
|
|
|
|
res = gdb_sigmask (0, NULL, &original_signal_mask);
|
|
if (res == -1)
|
|
perror_with_name (("sigprocmask"));
|
|
|
|
bool found_preinstalled = false;
|
|
|
|
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. 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. */
|
|
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"));
|
|
}
|
|
#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 = gdb_sigmask (SIG_SETMASK, &original_signal_mask, NULL);
|
|
if (res == -1)
|
|
perror_with_name (("sigprocmask"));
|
|
#endif
|
|
}
|