Allow remote debugging over a Unix local domain socket.

Message ID 20180903121736.5246-2-john@darrington.wattle.id.au
State New, archived
Headers

Commit Message

John Darrington Sept. 3, 2018, 12:17 p.m. UTC
  Extend the "target remote" and "target extended-remote" commands
such that if the filename provided is a Unix local domain (AF_UNIX)
socket, then it'll be treated as such, instead of trying to open
it as if it were a character device.

gdb/ChangeLog:
	* NEWS: Mention changed commands.
	* configure.ac (SER_HARDWIRE): Add ser-socket.o.
	* ser-socket.c: New file.
	* Makefile.in: Add new file.
	* serial.c (serial_open): Check if filename is a socket
	  and lookup the appropriate interface accordingly.

gdb/doc/ChangeLog:
	* gdb.texinfo (Remote Connection Commands):  Describe
	  the changes to target remote and target extended-remote
	  relating to Unix domain sockets.
---
 gdb/Makefile.in     |   1 +
 gdb/NEWS            |   5 +++
 gdb/configure       |   1 +
 gdb/configure.ac    |   1 +
 gdb/doc/gdb.texinfo |  22 +++++++++-
 gdb/ser-socket.c    | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/serial.c        |  12 +++++-
 7 files changed, 155 insertions(+), 2 deletions(-)
 create mode 100644 gdb/ser-socket.c
  

Comments

Tom Tromey Sept. 7, 2018, 9:05 p.m. UTC | #1
>>>>> "John" == John Darrington <john@darrington.wattle.id.au> writes:

John> Extend the "target remote" and "target extended-remote" commands
John> such that if the filename provided is a Unix local domain (AF_UNIX)
John> socket, then it'll be treated as such, instead of trying to open
John> it as if it were a character device.

I think Pedro should have the final review on this, since he had more
comments the last time around.

John> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
John> index 5068c0ac81..dae62c1787 100644
John> --- a/gdb/doc/gdb.texinfo
John> +++ b/gdb/doc/gdb.texinfo
John> @@ -20703,7 +20703,8 @@ programs.
 
John>  @code{target} command.
 
John> +
John> +@item target remote @var{local-socket}
John> +@itemx target extended-remote @var{local-socket}

That looked like one extra newline in there to me.

John> +#ifndef UNIX_MAX_PATH
John> +# define UNIX_MAX_PATH 108
John> +#endif

As mentioned before, use the sizeof thing.
Now that there are 3 copies of this in gdb, it would be good to unify
them somewhere in common/.

I see:

./gdbserver/tracepoint.c6861:#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
./common/agent.c131:#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)

The linux unix(7) man page has some stuff to say about the sizes.

In another message you said:

John> I thought posix required a minimum of 108.

I don't know, but if other platforms do it differently, then gdb has to
adapt to them and not just go by POSIX.

One alternative in these cases is to see if there is a gnulib module we
could use.

thanks,
Tom
  
John Darrington Sept. 8, 2018, 4:21 a.m. UTC | #2
On Fri, Sep 07, 2018 at 03:05:59PM -0600, Tom Tromey wrote:
     >>>>> "John" == John Darrington <john@darrington.wattle.id.au> writes:
     
     John> Extend the "target remote" and "target extended-remote" commands
     John> such that if the filename provided is a Unix local domain (AF_UNIX)
     John> socket, then it'll be treated as such, instead of trying to open
     John> it as if it were a character device.
     
     I think Pedro should have the final review on this, since he had more
     comments the last time around.

Okay.  Pedro?
     
     John> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
     John> index 5068c0ac81..dae62c1787 100644
     John> --- a/gdb/doc/gdb.texinfo
     John> +++ b/gdb/doc/gdb.texinfo
     John> @@ -20703,7 +20703,8 @@ programs.
      
     John>  @code{target} command.
      
     John> +
     John> +@item target remote @var{local-socket}
     John> +@itemx target extended-remote @var{local-socket}
     
     That looked like one extra newline in there to me.
I will fix that.
     
     Now that there are 3 copies of this in gdb, it would be good to unify
     them somewhere in common/.

I agree.  But shouldn't that be the subject of a separate change?


J'
  
John Darrington Sept. 11, 2018, 5:20 a.m. UTC | #3
On Sat, Sep 08, 2018 at 06:21:58AM +0200, John Darrington wrote:
     On Fri, Sep 07, 2018 at 03:05:59PM -0600, Tom Tromey wrote:
          >>>>> "John" == John Darrington <john@darrington.wattle.id.au> writes:
          
          John> Extend the "target remote" and "target extended-remote" commands
          John> such that if the filename provided is a Unix local domain (AF_UNIX)
          John> socket, then it'll be treated as such, instead of trying to open
          John> it as if it were a character device.
          
          I think Pedro should have the final review on this, since he had more
          comments the last time around.
     
     Okay.  Pedro?
          

... it seems that Pedro doesn't have anything more to say.   So I'll
push this in the next day or two if he doesn't pipe up.

J'
  
Tom Tromey Sept. 11, 2018, 5:22 a.m. UTC | #4
>>>>> "John" == John Darrington <john@darrington.wattle.id.au> writes:

John> ... it seems that Pedro doesn't have anything more to say.   So I'll
John> push this in the next day or two if he doesn't pipe up.

No, please wait.
This weekend was the GNU Cauldron.  He may be traveling.

Tom
  
Pedro Alves Sept. 11, 2018, 9:34 a.m. UTC | #5
On 09/11/2018 06:22 AM, Tom Tromey wrote:
>>>>>> "John" == John Darrington <john@darrington.wattle.id.au> writes:
> 
> John> ... it seems that Pedro doesn't have anything more to say.   So I'll
> John> push this in the next day or two if he doesn't pipe up.
> 
> No, please wait.
> This weekend was the GNU Cauldron.  He may be traveling.

Yes, I was.  Thanks for the patience.

Thanks,
Pedro Alves
  
John Darrington Oct. 1, 2018, 6:12 p.m. UTC | #6
On Mon, Sep 10, 2018 at 11:22:36PM -0600, Tom Tromey wrote:
     >>>>> "John" == John Darrington <john@darrington.wattle.id.au> writes:
     
     John> ... it seems that Pedro doesn't have anything more to say.   So I'll
     John> push this in the next day or two if he doesn't pipe up.
     
     No, please wait.
     This weekend was the GNU Cauldron.  He may be traveling.
     
     Tom

How much longer should I wait?

It's been four weeks since I posted this, and after several reminders
Pedro has not said anything.    So I think it's reasonable to assume
that either he doesn't see any more problems with this patch or that he
believes any problems that there are, are too small to worry about.

It's not reasonable to wait indefinitely in case he does eventually
have something to say.

J'
  
Pedro Alves Oct. 1, 2018, 6:25 p.m. UTC | #7
On 10/01/2018 07:12 PM, John Darrington wrote:

> How much longer should I wait?
> 
> It's been four weeks since I posted this, and after several reminders
> Pedro has not said anything.    So I think it's reasonable to assume
> that either he doesn't see any more problems with this patch or that he
> believes any problems that there are, are too small to worry about.
> 
> It's not reasonable to wait indefinitely in case he does eventually
> have something to say.

September has been complicated.  After Cauldron, I was out of office the
whole of last week for an annual team meeting.  Looking at the patch now.

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 118c3c8062..4646ade6c1 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2323,6 +2323,7 @@  ALLDEPFILES = \
 	ser-go32.c \
 	ser-mingw.c \
 	ser-pipe.c \
+	ser-socket.c \
 	ser-tcp.c \
 	sh-nbsd-nat.c \
 	sh-nbsd-tdep.c \
diff --git a/gdb/NEWS b/gdb/NEWS
index a7a3674375..e5926897a0 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -36,6 +36,11 @@  maint show dwarf unwinders
 
 * Changed commands
 
+target remote FILENAME
+target extended-remote FILENAME
+  If FILENAME is a Unix domain socket, GDB will attempt to connect
+  to this socket instead of opening FILENAME as a character device.
+
 thread apply [all | COUNT | -COUNT] [FLAG]... COMMAND
   The 'thread apply' command accepts new FLAG arguments.
   FLAG arguments allow to control what output to produce and how to handle
diff --git a/gdb/configure b/gdb/configure
index 9cd0036848..21c4f8b6af 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -15586,6 +15586,7 @@  case ${host} in
   *go32* ) SER_HARDWIRE=ser-go32.o ;;
   *djgpp* ) SER_HARDWIRE=ser-go32.o ;;
   *mingw32*) SER_HARDWIRE="ser-base.o ser-tcp.o ser-mingw.o" ;;
+  *) SER_HARDWIRE="$SER_HARDWIRE ser-socket.o" ;;
 esac
 
 
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 13bc5f9a8f..07c874df96 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -1875,6 +1875,7 @@  case ${host} in
   *go32* ) SER_HARDWIRE=ser-go32.o ;;
   *djgpp* ) SER_HARDWIRE=ser-go32.o ;;
   *mingw32*) SER_HARDWIRE="ser-base.o ser-tcp.o ser-mingw.o" ;;
+  *) SER_HARDWIRE="$SER_HARDWIRE ser-socket.o" ;;
 esac
 AC_SUBST(SER_HARDWIRE)
 
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 5068c0ac81..dae62c1787 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -20703,7 +20703,8 @@  programs.
 
 @subsection Remote Connection Commands
 @cindex remote connection commands
-@value{GDBN} can communicate with the target over a serial line, or
+@value{GDBN} can communicate with the target over a serial line, a
+local Unix domain socket, or
 over an @acronym{IP} network using @acronym{TCP} or @acronym{UDP}.  In
 each case, @value{GDBN} uses the same protocol for debugging your
 program; only the medium carrying the debugging packets varies.  The
@@ -20728,6 +20729,25 @@  If you're using a serial line, you may want to give @value{GDBN} the
 (@pxref{Remote Configuration, set serial baud}) before the
 @code{target} command.
 
+
+@item target remote @var{local-socket}
+@itemx target extended-remote @var{local-socket}
+@cindex local socket, @code{target remote}
+@cindex Unix domain socket
+Use @var{local-socket} to communicate with the target.  For example,
+to use a local Unix domain socket bound to the file system entry @file{/tmp/gdb-socket0}:
+
+@smallexample
+target remote /tmp/gdb-socket0
+@end smallexample
+
+Note that this command has the same form as the command to connect
+to a serial line.  @value{GDBN} will automatically determine which
+kind of file you have specified and will make the appropriate kind
+of connection.
+This feature is not available if the host system does not support
+Unix domain sockets.
+
 @item target remote @code{@var{host}:@var{port}}
 @itemx target remote @code{@var{[host]}:@var{port}}
 @itemx target remote @code{tcp:@var{host}:@var{port}}
diff --git a/gdb/ser-socket.c b/gdb/ser-socket.c
new file mode 100644
index 0000000000..6275447e2b
--- /dev/null
+++ b/gdb/ser-socket.c
@@ -0,0 +1,115 @@ 
+/* Serial interface for local domain connections on Un*x like systems.
+
+   Copyright (C) 1992-2018 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 "serial.h"
+#include "ser-base.h"
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+/* Open a AF_UNIX socket.  */
+int
+socket_open (struct serial *scb, const char *name)
+{
+  struct sockaddr_un addr;
+
+  memset (&addr, 0, sizeof addr);
+  addr.sun_family = AF_UNIX;
+#ifndef UNIX_MAX_PATH
+# define UNIX_MAX_PATH 108
+#endif
+  strncpy (addr.sun_path, name, UNIX_MAX_PATH - 1);
+
+  int sock = socket (AF_UNIX, SOCK_STREAM, 0);
+
+  if (connect (sock, (struct sockaddr *) &addr,
+	       sizeof (struct sockaddr_un)) < 0)
+    {
+      close (sock);
+      scb->fd = -1;
+      return -1;
+    }
+
+  scb->fd = sock;
+
+  return 0;
+}
+
+void
+socket_close (struct serial *scb)
+{
+  if (scb->fd == -1)
+    return;
+
+  close (scb->fd);
+  scb->fd = -1;
+}
+
+static int
+socket_read_prim (struct serial *scb, size_t count)
+{
+  return recv (scb->fd, scb->buf, count, 0);
+}
+
+static int
+socket_write_prim (struct serial *scb, const void *buf, size_t count)
+{
+  return send (scb->fd, buf, count, 0);
+}
+
+static int
+ser_socket_send_break (struct serial *scb)
+{
+  /* Send telnet IAC and BREAK characters.  */
+  return (serial_write (scb, "\377\363", 2));
+}
+
+/* The SOCKET ops.  */
+
+static const struct serial_ops socket_ops =
+{
+  "socket",
+  socket_open,
+  socket_close,
+  NULL,
+  ser_base_readchar,
+  ser_base_write,
+  ser_base_flush_output,
+  ser_base_flush_input,
+  ser_socket_send_break,
+  ser_base_raw,
+  ser_base_get_tty_state,
+  ser_base_copy_tty_state,
+  ser_base_set_tty_state,
+  ser_base_print_tty_state,
+  ser_base_setbaudrate,
+  ser_base_setstopbits,
+  ser_base_setparity,
+  ser_base_drain_output,
+  ser_base_async,
+  socket_read_prim,
+  socket_write_prim
+};
+
+void
+_initialize_ser_socket (void)
+{
+  serial_add_interface (&socket_ops);
+}
diff --git a/gdb/serial.c b/gdb/serial.c
index fb2b212918..f1fcd95e3c 100644
--- a/gdb/serial.c
+++ b/gdb/serial.c
@@ -213,7 +213,17 @@  serial_open (const char *name)
   else if (strchr (name, ':'))
     ops = serial_interface_lookup ("tcp");
   else
-    ops = serial_interface_lookup ("hardwire");
+    {
+#ifndef USE_WIN32API
+      /* Check to see if name is a socket.  If it is, then treat it
+         as such.  Otherwise assume that it's a character device.  */
+      struct stat sb;
+      if (0 == stat (name, &sb) && ((sb.st_mode & S_IFMT) == S_IFSOCK))
+	ops = serial_interface_lookup ("socket");
+      else
+#endif
+	ops = serial_interface_lookup ("hardwire");
+    }
 
   if (!ops)
     return NULL;