From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7944 invoked by alias); 5 Sep 2018 15:27:06 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 7848 invoked by uid 89); 5 Sep 2018 15:27:06 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.0 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,SPF_PASS autolearn=ham version=3.3.2 spammy=Describe, Connection, connections X-HELO: jocasta.intra Received: from de.cellform.com (HELO jocasta.intra) (88.217.224.109) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 05 Sep 2018 15:27:02 +0000 Received: from jocasta.intra (localhost [127.0.0.1]) by jocasta.intra (8.15.2/8.15.2/Debian-8) with ESMTPS id w85FQxrl007628 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 5 Sep 2018 17:26:59 +0200 Received: (from john@localhost) by jocasta.intra (8.15.2/8.15.2/Submit) id w85FQxhc007627; Wed, 5 Sep 2018 17:26:59 +0200 From: John Darrington To: gdb-patches@sourceware.org Cc: John Darrington Subject: [PATCH] Allow remote debugging over a Unix local domain socket. Date: Wed, 05 Sep 2018 15:27:00 -0000 Message-Id: <20180905152656.7565-2-john@darrington.wattle.id.au> In-Reply-To: <20180905152656.7565-1-john@darrington.wattle.id.au> References: <20180905152656.7565-1-john@darrington.wattle.id.au> X-SW-Source: 2018-09/txt/msg00080.txt.bz2 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. * ser-local.c: New file. * configure.ac (SER_HARDWIRE): Add ser-local.o. * 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-local.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/serial.c | 12 +++++- 7 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 gdb/ser-local.c diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 118c3c8062..39bbe9be88 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -2323,6 +2323,7 @@ ALLDEPFILES = \ ser-go32.c \ ser-mingw.c \ ser-pipe.c \ + ser-local.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..95f246d013 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-local.o" ;; esac diff --git a/gdb/configure.ac b/gdb/configure.ac index 13bc5f9a8f..9a919eaa1e 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-local.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-local.c b/gdb/ser-local.c new file mode 100644 index 0000000000..a3b8248ae5 --- /dev/null +++ b/gdb/ser-local.c @@ -0,0 +1,116 @@ +/* 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 . */ + +#include "defs.h" +#include "serial.h" +#include "ser-base.h" + +#include +#include + +#ifndef UNIX_PATH_MAX +#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path) +#endif + +/* Open a AF_UNIX socket. */ +int +local_open (struct serial *scb, const char *name) +{ + struct sockaddr_un addr; + + if (strlen(name) > UNIX_PATH_MAX - 1) + { + warning (_("The socket name is too long. It may be no longer than %zu bytes."), + UNIX_PATH_MAX - 1L); + return -1; + } + + memset (&addr, 0, sizeof addr); + addr.sun_family = AF_UNIX; + strncpy (addr.sun_path, name, UNIX_PATH_MAX - 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 +local_close (struct serial *scb) +{ + if (scb->fd == -1) + return; + + close (scb->fd); + scb->fd = -1; +} + +static int +local_read_prim (struct serial *scb, size_t count) +{ + return recv (scb->fd, scb->buf, count, 0); +} + +static int +local_write_prim (struct serial *scb, const void *buf, size_t count) +{ + return send (scb->fd, buf, count, 0); +} + +/* The local socket ops. */ + +static const struct serial_ops local_ops = +{ + "local", + local_open, + local_close, + NULL, + ser_base_readchar, + ser_base_write, + ser_base_flush_output, + ser_base_flush_input, + ser_base_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, + local_read_prim, + local_write_prim +}; + +void +_initialize_ser_socket (void) +{ + serial_add_interface (&local_ops); +} diff --git a/gdb/serial.c b/gdb/serial.c index fb2b212918..c04e011012 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 ("local"); + else +#endif + ops = serial_interface_lookup ("hardwire"); + } if (!ops) return NULL; -- 2.11.0