summaryrefslogtreecommitdiff
path: root/gdbsupport
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2022-02-22 11:22:14 -0800
committerJohn Baldwin <jhb@FreeBSD.org>2022-02-22 11:22:14 -0800
commitea3e7446dcac18abb68772ce4e04b72815f49745 (patch)
treea06b1acf42f288af38f4b98d24542e415183c5c0 /gdbsupport
parent6a8fe63330c922255a4ced4b6491d35f6c384bba (diff)
downloadbinutils-gdb-ea3e7446dcac18abb68772ce4e04b72815f49745.tar.gz
gdbsupport: Add an event-pipe class.
This pulls out the implementation of an event pipe used to implement target async support in both linux-low.cc (gdbserver) and linux-nat.c (gdb). This will be used to replace the existing event pipe in linux-low.cc and linux-nat.c in future commits. Co-Authored-By: Lancelot SIX <lsix@lancelotsix.com>
Diffstat (limited to 'gdbsupport')
-rw-r--r--gdbsupport/Makefile.am5
-rw-r--r--gdbsupport/Makefile.in9
-rwxr-xr-xgdbsupport/configure15
-rw-r--r--gdbsupport/configure.ac3
-rw-r--r--gdbsupport/event-pipe.cc101
-rw-r--r--gdbsupport/event-pipe.h60
6 files changed, 190 insertions, 3 deletions
diff --git a/gdbsupport/Makefile.am b/gdbsupport/Makefile.am
index 6049fac20ef..1416027e1c9 100644
--- a/gdbsupport/Makefile.am
+++ b/gdbsupport/Makefile.am
@@ -35,6 +35,10 @@ if SELFTEST
selftest = selftest.cc
endif
+if HAVE_PIPE_OR_PIPE2
+eventpipe = event-pipe.cc
+endif
+
libgdbsupport_a_SOURCES = \
agent.cc \
btrace-common.cc \
@@ -74,6 +78,7 @@ libgdbsupport_a_SOURCES = \
tdesc.cc \
thread-pool.cc \
xml-utils.cc \
+ ${eventpipe} \
$(selftest)
# Double-check that no defines are missing from our configury.
diff --git a/gdbsupport/Makefile.in b/gdbsupport/Makefile.in
index 852e98c6bdf..bdceff3b56a 100644
--- a/gdbsupport/Makefile.in
+++ b/gdbsupport/Makefile.in
@@ -144,7 +144,8 @@ am__v_AR_0 = @echo " AR " $@;
am__v_AR_1 =
libgdbsupport_a_AR = $(AR) $(ARFLAGS)
libgdbsupport_a_LIBADD =
-@SELFTEST_TRUE@am__objects_1 = selftest.$(OBJEXT)
+@HAVE_PIPE_OR_PIPE2_TRUE@am__objects_1 = event-pipe.$(OBJEXT)
+@SELFTEST_TRUE@am__objects_2 = selftest.$(OBJEXT)
am_libgdbsupport_a_OBJECTS = agent.$(OBJEXT) btrace-common.$(OBJEXT) \
buffer.$(OBJEXT) cleanups.$(OBJEXT) common-debug.$(OBJEXT) \
common-exceptions.$(OBJEXT) common-inferior.$(OBJEXT) \
@@ -160,7 +161,7 @@ am_libgdbsupport_a_OBJECTS = agent.$(OBJEXT) btrace-common.$(OBJEXT) \
safe-strerror.$(OBJEXT) scoped_mmap.$(OBJEXT) search.$(OBJEXT) \
signals.$(OBJEXT) signals-state-save-restore.$(OBJEXT) \
tdesc.$(OBJEXT) thread-pool.$(OBJEXT) xml-utils.$(OBJEXT) \
- $(am__objects_1)
+ $(am__objects_1) $(am__objects_2)
libgdbsupport_a_OBJECTS = $(am_libgdbsupport_a_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -338,7 +339,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
-runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@@ -361,6 +361,7 @@ AM_CPPFLAGS = -I$(srcdir)/../include -I$(srcdir)/../gdb \
AM_CXXFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
noinst_LIBRARIES = libgdbsupport.a
@SELFTEST_TRUE@selftest = selftest.cc
+@HAVE_PIPE_OR_PIPE2_TRUE@eventpipe = event-pipe.cc
libgdbsupport_a_SOURCES = \
agent.cc \
btrace-common.cc \
@@ -400,6 +401,7 @@ libgdbsupport_a_SOURCES = \
tdesc.cc \
thread-pool.cc \
xml-utils.cc \
+ ${eventpipe} \
$(selftest)
all: config.h
@@ -482,6 +484,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/environ.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event-loop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event-pipe.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileio.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filestuff.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Po@am__quote@
diff --git a/gdbsupport/configure b/gdbsupport/configure
index afaba88ee94..2070a39fbb7 100755
--- a/gdbsupport/configure
+++ b/gdbsupport/configure
@@ -626,6 +626,8 @@ LTLIBOBJS
LIBOBJS
WERROR_CFLAGS
WARN_CFLAGS
+HAVE_PIPE_OR_PIPE2_FALSE
+HAVE_PIPE_OR_PIPE2_TRUE
SELFTEST_FALSE
SELFTEST_TRUE
LTLIBIPT
@@ -10002,6 +10004,15 @@ else
fi
+ if test x$ac_cv_func_pipe = xyes -o x$ac_cv_func_pipe2 = xyes ; then
+ HAVE_PIPE_OR_PIPE2_TRUE=
+ HAVE_PIPE_OR_PIPE2_FALSE='#'
+else
+ HAVE_PIPE_OR_PIPE2_TRUE='#'
+ HAVE_PIPE_OR_PIPE2_FALSE=
+fi
+
+
# Check the return and argument types of ptrace.
@@ -10597,6 +10608,10 @@ if test -z "${SELFTEST_TRUE}" && test -z "${SELFTEST_FALSE}"; then
as_fn_error $? "conditional \"SELFTEST\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${HAVE_PIPE_OR_PIPE2_TRUE}" && test -z "${HAVE_PIPE_OR_PIPE2_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_PIPE_OR_PIPE2\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
diff --git a/gdbsupport/configure.ac b/gdbsupport/configure.ac
index 55477d55c82..1f794605f3c 100644
--- a/gdbsupport/configure.ac
+++ b/gdbsupport/configure.ac
@@ -53,6 +53,9 @@ GDB_AC_COMMON
GDB_AC_SELFTEST
AM_CONDITIONAL(SELFTEST, $enable_unittests)
+AM_CONDITIONAL(HAVE_PIPE_OR_PIPE2,
+ [test x$ac_cv_func_pipe = xyes -o x$ac_cv_func_pipe2 = xyes ])
+
# Check the return and argument types of ptrace.
GDB_AC_PTRACE
diff --git a/gdbsupport/event-pipe.cc b/gdbsupport/event-pipe.cc
new file mode 100644
index 00000000000..2b56b2fac8e
--- /dev/null
+++ b/gdbsupport/event-pipe.cc
@@ -0,0 +1,101 @@
+/* Event pipe 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 "gdbsupport/common-defs.h"
+#include "gdbsupport/event-pipe.h"
+#include "gdbsupport/filestuff.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+event_pipe::~event_pipe ()
+{
+ if (is_open ())
+ close ();
+}
+
+/* See event-pipe.h. */
+
+bool
+event_pipe::open ()
+{
+ if (is_open ())
+ return false;
+
+ if (gdb_pipe_cloexec (m_fds) == -1)
+ return false;
+
+ if (fcntl (m_fds[0], F_SETFL, O_NONBLOCK) == -1
+ || fcntl (m_fds[1], F_SETFL, O_NONBLOCK) == -1)
+ {
+ close ();
+ return false;
+ }
+
+ return true;
+}
+
+/* See event-pipe.h. */
+
+void
+event_pipe::close ()
+{
+ ::close (m_fds[0]);
+ ::close (m_fds[1]);
+ m_fds[0] = -1;
+ m_fds[1] = -1;
+}
+
+/* See event-pipe.h. */
+
+void
+event_pipe::flush ()
+{
+ int ret;
+ char buf;
+
+ do
+ {
+ ret = read (m_fds[0], &buf, 1);
+ }
+ while (ret >= 0 || (ret == -1 && errno == EINTR));
+}
+
+/* See event-pipe.h. */
+
+void
+event_pipe::mark ()
+{
+ int ret;
+
+ /* It doesn't really matter what the pipe contains, as long we end
+ up with something in it. Might as well flush the previous
+ left-overs. */
+ flush ();
+
+ do
+ {
+ ret = write (m_fds[1], "+", 1);
+ }
+ while (ret == -1 && errno == EINTR);
+
+ /* Ignore EAGAIN. If the pipe is full, the event loop will already
+ be awakened anyway. */
+}
diff --git a/gdbsupport/event-pipe.h b/gdbsupport/event-pipe.h
new file mode 100644
index 00000000000..50679e470e4
--- /dev/null
+++ b/gdbsupport/event-pipe.h
@@ -0,0 +1,60 @@
+/* Event pipe 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/>. */
+
+#ifndef COMMON_EVENT_PIPE_H
+#define COMMON_EVENT_PIPE_H
+
+/* An event pipe used as a waitable file in the event loop in place of
+ some other event associated with a signal. The handler for the
+ signal marks the event pipe to force a wakeup in the event loop.
+ This uses the well-known self-pipe trick. */
+
+class event_pipe
+{
+public:
+ event_pipe() = default;
+ ~event_pipe();
+
+ DISABLE_COPY_AND_ASSIGN (event_pipe);
+
+ /* Create a new pipe. */
+ bool open ();
+
+ /* Close the pipe. */
+ void close ();
+
+ /* True if the event pipe has been opened. */
+ bool is_open () const
+ { return m_fds[0] != -1; }
+
+ /* The file descriptor of the waitable file to use in the event
+ loop. */
+ int event_fd () const
+ { return m_fds[0]; }
+
+ /* Flush the event pipe. */
+ void flush ();
+
+ /* Put something in the pipe, so the event loop wakes up. */
+ void mark ();
+private:
+ int m_fds[2] = { -1, -1 };
+};
+
+#endif /* COMMON_EVENT_PIPE_H */