mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
4 Commits
gdb-13.1-r
...
users/palv
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c73fc9439a | ||
|
|
5e9f71e1cd | ||
|
|
68e41281e8 | ||
|
|
148e7536c6 |
@@ -461,6 +461,7 @@ SELFTESTS_SRCS = \
|
||||
unittests/mkdir-recursive-selftests.c \
|
||||
unittests/rsp-low-selftests.c \
|
||||
unittests/scoped_fd-selftests.c \
|
||||
unittests/scoped_ignore_signal-selftests.c \
|
||||
unittests/scoped_mmap-selftests.c \
|
||||
unittests/scoped_restore-selftests.c \
|
||||
unittests/search-memory-selftests.c \
|
||||
@@ -1336,7 +1337,6 @@ HFILES_NO_SRCDIR = \
|
||||
inf-ptrace.h \
|
||||
infcall.h \
|
||||
inferior.h \
|
||||
inflow.h \
|
||||
inline-frame.h \
|
||||
interps.h \
|
||||
jit.h \
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#include "gdbsupport/gdb_optional.h"
|
||||
#include "gdbsupport/gdb_unlinker.h"
|
||||
#include "gdbsupport/pathstuff.h"
|
||||
#include <signal.h>
|
||||
#include "gdbsupport/scoped_ignore_signal.h"
|
||||
|
||||
|
||||
|
||||
@@ -634,33 +634,6 @@ print_callback (void *ignore, const char *message)
|
||||
fputs_filtered (message, gdb_stderr);
|
||||
}
|
||||
|
||||
/* RAII class used to ignore SIGPIPE in a scope. */
|
||||
|
||||
class scoped_ignore_sigpipe
|
||||
{
|
||||
public:
|
||||
scoped_ignore_sigpipe ()
|
||||
{
|
||||
#ifdef SIGPIPE
|
||||
m_osigpipe = signal (SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
}
|
||||
|
||||
~scoped_ignore_sigpipe ()
|
||||
{
|
||||
#ifdef SIGPIPE
|
||||
signal (SIGPIPE, m_osigpipe);
|
||||
#endif
|
||||
}
|
||||
|
||||
DISABLE_COPY_AND_ASSIGN (scoped_ignore_sigpipe);
|
||||
|
||||
private:
|
||||
#ifdef SIGPIPE
|
||||
sighandler_t m_osigpipe = NULL;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Process the compilation request. On success it returns the object
|
||||
and source file names. On an error condition, error () is
|
||||
called. */
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "inferior.h"
|
||||
#include "inflow.h"
|
||||
#include "terminal.h"
|
||||
#include "gdbcore.h"
|
||||
#include "regcache.h"
|
||||
|
||||
@@ -29,12 +29,12 @@
|
||||
#include <fcntl.h>
|
||||
#include "gdbsupport/gdb_select.h"
|
||||
|
||||
#include "inflow.h"
|
||||
#include "gdbcmd.h"
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
#include <termios.h>
|
||||
#endif
|
||||
#include "gdbsupport/job-control.h"
|
||||
#include "gdbsupport/scoped_ignore_sigttou.h"
|
||||
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
#include "gdb_bfd.h"
|
||||
#include "inflow.h"
|
||||
#include "auxv.h"
|
||||
#include "procfs.h"
|
||||
#include "observable.h"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "gdbcmd.h"
|
||||
#include "gdbsupport/filestuff.h"
|
||||
#include <termios.h>
|
||||
#include "inflow.h"
|
||||
#include "gdbsupport/scoped_ignore_sigttou.h"
|
||||
|
||||
struct hardwire_ttystate
|
||||
{
|
||||
|
||||
125
gdb/unittests/scoped_ignore_signal-selftests.c
Normal file
125
gdb/unittests/scoped_ignore_signal-selftests.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/* Self tests for scoped_ignored_signal for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 2021 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 "defs.h"
|
||||
#include "gdbsupport/scoped_ignore_signal.h"
|
||||
#include "gdbsupport/selftest.h"
|
||||
#include "gdbsupport/scope-exit.h"
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
namespace selftests {
|
||||
namespace scoped_ignore_sig {
|
||||
|
||||
#ifdef SIGPIPE
|
||||
|
||||
/* True if the SIGPIPE handler ran. */
|
||||
static sig_atomic_t got_sigpipe = 0;
|
||||
|
||||
/* SIGPIPE handler for testing. */
|
||||
|
||||
static void
|
||||
handle_sigpipe (int)
|
||||
{
|
||||
got_sigpipe = 1;
|
||||
}
|
||||
|
||||
/* Test scoped_ignore_sigpipe. */
|
||||
|
||||
static void
|
||||
test_sigpipe ()
|
||||
{
|
||||
auto *osig = signal (SIGPIPE, handle_sigpipe);
|
||||
SCOPE_EXIT { signal (SIGPIPE, osig); };
|
||||
|
||||
#ifdef HAVE_SIGPROCMASK
|
||||
/* Make sure SIGPIPE isn't blocked. */
|
||||
sigset_t set, old_state;
|
||||
sigemptyset (&set);
|
||||
sigaddset (&set, SIGPIPE);
|
||||
sigprocmask (SIG_UNBLOCK, &set, &old_state);
|
||||
SCOPE_EXIT { sigprocmask (SIG_SETMASK, &old_state, nullptr); };
|
||||
#endif
|
||||
|
||||
/* Create pipe, and close read end so that writes to the pipe fail
|
||||
with EPIPE. */
|
||||
|
||||
int fd[2];
|
||||
char c = 0xff;
|
||||
int r;
|
||||
|
||||
r = pipe (fd);
|
||||
SELF_CHECK (r == 0);
|
||||
|
||||
close (fd[0]); SCOPE_EXIT { close (fd[1]); };
|
||||
|
||||
/* Check that writing to the pipe results in EPIPE. EXPECT_SIG
|
||||
indicates whether a SIGPIPE signal is expected. */
|
||||
auto check_pipe_write = [&] (bool expect_sig)
|
||||
{
|
||||
got_sigpipe = 0;
|
||||
errno = 0;
|
||||
|
||||
r = write (fd[1], &c, 1);
|
||||
SELF_CHECK (r == -1 && errno == EPIPE
|
||||
&& got_sigpipe == expect_sig);
|
||||
};
|
||||
|
||||
/* Check that without a scoped_ignore_sigpipe in scope we indeed get
|
||||
a SIGPIPE signal. */
|
||||
check_pipe_write (true);
|
||||
|
||||
/* Now check that with a scoped_ignore_sigpipe in scope, SIGPIPE is
|
||||
ignored/blocked. */
|
||||
{
|
||||
scoped_ignore_sigpipe ignore1;
|
||||
|
||||
check_pipe_write (false);
|
||||
|
||||
/* Check that scoped_ignore_sigpipe nests correctly. */
|
||||
{
|
||||
scoped_ignore_sigpipe ignore2;
|
||||
|
||||
check_pipe_write (false);
|
||||
}
|
||||
|
||||
/* If nesting works correctly, this write results in no
|
||||
SIGPIPE. */
|
||||
check_pipe_write (false);
|
||||
}
|
||||
|
||||
/* No scoped_ignore_sigpipe is is scope anymore, so this should
|
||||
result in a SIGPIPE signal. */
|
||||
check_pipe_write (true);
|
||||
}
|
||||
|
||||
#endif /* SIGPIPE */
|
||||
|
||||
} /* namespace scoped_ignore_sig */
|
||||
} /* namespace selftests */
|
||||
|
||||
void _initialize_scoped_ignore_signal_selftests ();
|
||||
void
|
||||
_initialize_scoped_ignore_signal_selftests ()
|
||||
{
|
||||
#ifdef SIGPIPE
|
||||
selftests::register_test ("scoped_ignore_sigpipe",
|
||||
selftests::scoped_ignore_sig::test_sigpipe);
|
||||
#endif
|
||||
}
|
||||
97
gdbsupport/scoped_ignore_signal.h
Normal file
97
gdbsupport/scoped_ignore_signal.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/* Support for ignoring signals.
|
||||
|
||||
Copyright (C) 2021 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 SCOPED_IGNORE_SIGNAL_H
|
||||
#define SCOPED_IGNORE_SIGNAL_H
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
/* RAII class used to ignore a signal in a scope. If sigprocmask is
|
||||
supported, then the signal is only ignored by the calling thread.
|
||||
Otherwise, the signal disposition is set to SIG_IGN, which affects
|
||||
the whole process. */
|
||||
|
||||
template <int Sig>
|
||||
class scoped_ignore_signal
|
||||
{
|
||||
public:
|
||||
scoped_ignore_signal ()
|
||||
{
|
||||
#ifdef HAVE_SIGPROCMASK
|
||||
sigset_t set, old_state;
|
||||
|
||||
sigemptyset (&set);
|
||||
sigaddset (&set, Sig);
|
||||
sigprocmask (SIG_BLOCK, &set, &old_state);
|
||||
m_was_blocked = sigismember (&old_state, Sig);
|
||||
#else
|
||||
m_osig = signal (Sig, SIG_IGN);
|
||||
#endif
|
||||
}
|
||||
|
||||
~scoped_ignore_signal ()
|
||||
{
|
||||
#ifdef HAVE_SIGPROCMASK
|
||||
if (!m_was_blocked)
|
||||
{
|
||||
sigset_t set;
|
||||
const timespec zero_timeout = {};
|
||||
|
||||
sigemptyset (&set);
|
||||
sigaddset (&set, Sig);
|
||||
|
||||
/* If we got a pending Sig signal, consume it before
|
||||
unblocking. */
|
||||
sigtimedwait (&set, nullptr, &zero_timeout);
|
||||
|
||||
sigprocmask (SIG_UNBLOCK, &set, nullptr);
|
||||
}
|
||||
#else
|
||||
signal (Sig, m_osig);
|
||||
#endif
|
||||
}
|
||||
|
||||
DISABLE_COPY_AND_ASSIGN (scoped_ignore_signal);
|
||||
|
||||
private:
|
||||
#ifdef HAVE_SIGPROCMASK
|
||||
bool m_was_blocked;
|
||||
#else
|
||||
sighandler_t m_osig;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct scoped_ignore_signal_nop
|
||||
{
|
||||
/* Note, these can't both be "= default", because otherwise the
|
||||
compiler warns that variables of this type are not used. */
|
||||
scoped_ignore_signal_nop ()
|
||||
{}
|
||||
~scoped_ignore_signal_nop ()
|
||||
{}
|
||||
DISABLE_COPY_AND_ASSIGN (scoped_ignore_signal_nop);
|
||||
};
|
||||
|
||||
#ifdef SIGPIPE
|
||||
using scoped_ignore_sigpipe = scoped_ignore_signal<SIGPIPE>;
|
||||
#else
|
||||
using scoped_ignore_sigpipe = scoped_ignore_signal_nop;
|
||||
#endif
|
||||
|
||||
#endif /* SCOPED_IGNORE_SIGNAL_H */
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Low level interface to ptrace, for GDB when running under Unix.
|
||||
/* Support for signoring SIGTTOU.
|
||||
|
||||
Copyright (C) 2003-2021 Free Software Foundation, Inc.
|
||||
|
||||
@@ -17,40 +17,64 @@
|
||||
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 INFLOW_H
|
||||
#define INFLOW_H
|
||||
#ifndef SCOPED_IGNORE_SIGTTOU_H
|
||||
#define SCOPED_IGNORE_SIGTTOU_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include "gdbsupport/scoped_ignore_signal.h"
|
||||
#include "gdbsupport/job-control.h"
|
||||
|
||||
/* RAII class used to ignore SIGTTOU in a scope. */
|
||||
#ifdef SIGTTOU
|
||||
|
||||
/* Simple wrapper that allows lazy initialization / destruction of T.
|
||||
Slightly more efficient than gdb::optional, because it doesn't
|
||||
carry storage to track whether the object has been initialized. */
|
||||
template<typename T>
|
||||
class lazy_init
|
||||
{
|
||||
public:
|
||||
void emplace ()
|
||||
{
|
||||
new (m_buf) T ();
|
||||
}
|
||||
|
||||
void reset ()
|
||||
{
|
||||
reinterpret_cast <T *> (m_buf)->~T ();
|
||||
}
|
||||
|
||||
private:
|
||||
alignas (T) gdb_byte m_buf[sizeof (T)];
|
||||
};
|
||||
|
||||
/* RAII class used to ignore SIGTTOU in a scope. This isn't simply
|
||||
scoped_ignore_signal<SIGTTOU> because we want to check the
|
||||
`job_control' global. */
|
||||
|
||||
class scoped_ignore_sigttou
|
||||
{
|
||||
public:
|
||||
scoped_ignore_sigttou ()
|
||||
{
|
||||
#ifdef SIGTTOU
|
||||
if (job_control)
|
||||
m_osigttou = signal (SIGTTOU, SIG_IGN);
|
||||
#endif
|
||||
m_ignore_signal.emplace ();
|
||||
}
|
||||
|
||||
~scoped_ignore_sigttou ()
|
||||
{
|
||||
#ifdef SIGTTOU
|
||||
if (job_control)
|
||||
signal (SIGTTOU, m_osigttou);
|
||||
#endif
|
||||
m_ignore_signal.reset ();
|
||||
}
|
||||
|
||||
DISABLE_COPY_AND_ASSIGN (scoped_ignore_sigttou);
|
||||
|
||||
private:
|
||||
#ifdef SIGTTOU
|
||||
sighandler_t m_osigttou = NULL;
|
||||
#endif
|
||||
lazy_init<scoped_ignore_signal<SIGTTOU>> m_ignore_signal;
|
||||
};
|
||||
|
||||
#endif /* inflow.h */
|
||||
#else
|
||||
|
||||
using scoped_ignore_sigttou = scoped_ignore_signal_nop;
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SCOPED_IGNORE_SIGTTOU_H */
|
||||
Reference in New Issue
Block a user