Allow remote debugging over a Unix local domain socket.

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-uds.c: New file.
	* configure.ac (SER_HARDWIRE): Add ser-uds.o.
	* configure: Regenerate.
	* 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.
This commit is contained in:
John Darrington 2018-08-29 21:51:26 +02:00
parent eb528ad18b
commit c1168a2f66
9 changed files with 173 additions and 2 deletions

View File

@ -1,3 +1,13 @@
2018-10-02 John Darrington <john@darrington.wattle.id.au>
* NEWS: Mention changed commands.
* ser-uds.c: New file.
* configure.ac (SER_HARDWIRE): Add ser-uds.o.
* configure: Regenerate.
* Makefile.in: Add new file.
* serial.c (serial_open): Check if filename is a socket
and lookup the appropriate interface accordingly.
2018-10-01 Alan Hayward <alan.hayward@arm.com>
* aarch64-linux-tdep.c (AARCH64_SIGCONTEXT_RESERVED_OFFSET): Add

View File

@ -2323,6 +2323,7 @@ ALLDEPFILES = \
ser-mingw.c \
ser-pipe.c \
ser-tcp.c \
ser-uds.c \
sh-nbsd-nat.c \
sh-nbsd-tdep.c \
sh-tdep.c \

View File

@ -69,6 +69,11 @@ info proc files
* 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

1
gdb/configure vendored
View File

@ -15592,6 +15592,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-uds.o" ;;
esac

View File

@ -1853,6 +1853,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-uds.o" ;;
esac
AC_SUBST(SER_HARDWIRE)

View File

@ -1,3 +1,9 @@
2018-10-02 John Darrington <john@darrington.wattle.id.au>
* gdb.texinfo (Remote Connection Commands): Describe
the changes to target remote and target extended-remote
relating to Unix domain sockets.
2018-10-01 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Configure Options): Document configure options.

View File

@ -20782,7 +20782,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
@ -20807,6 +20808,24 @@ 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}}

118
gdb/ser-uds.c Normal file
View File

@ -0,0 +1,118 @@
/* 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>
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
#endif
/* Open an AF_UNIX socket. */
static int
uds_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 %s bytes."),
pulongest (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;
}
static void
uds_close (struct serial *scb)
{
if (scb->fd == -1)
return;
close (scb->fd);
scb->fd = -1;
}
static int
uds_read_prim (struct serial *scb, size_t count)
{
return recv (scb->fd, scb->buf, count, 0);
}
static int
uds_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 uds_ops =
{
"local",
uds_open,
uds_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,
uds_read_prim,
uds_write_prim
};
void
_initialize_ser_socket (void)
{
serial_add_interface (&uds_ops);
}

View File

@ -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 (stat (name, &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFSOCK)
ops = serial_interface_lookup ("local");
else
#endif
ops = serial_interface_lookup ("hardwire");
}
if (!ops)
return NULL;