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>
This commit is contained in:
John Baldwin
2022-02-22 11:22:14 -08:00
parent 6a8fe63330
commit ea3e7446dc
6 changed files with 190 additions and 3 deletions

View File

@@ -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.

View File

@@ -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@

15
gdbsupport/configure vendored
View File

@@ -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

View File

@@ -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

101
gdbsupport/event-pipe.cc Normal file
View File

@@ -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. */
}

60
gdbsupport/event-pipe.h Normal file
View File

@@ -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 */