This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

gdb remote with unix socket


Hi there!

I needed to work with unix domain socket (I use kgdb in vmware with
serial port mapping to unix socket), and took ser-tcp.c as a template
to make this support. I do not subscribed to this list, so sorry, if
there were such solutions here. Here is patch:

diff -urN gdb-6.0.orig/gdb/configure gdb-6.0/gdb/configure
--- gdb-6.0.orig/gdb/configure	2004-03-02 18:00:01.000000000 +0200
+++ gdb-6.0/gdb/configure	2004-03-02 18:02:23.000000000 +0200
@@ -8997,7 +8997,7 @@
 echo "$ac_t""$gdb_cv_os_cygwin" 1>&6
 
 
-SER_HARDWIRE="ser-unix.o ser-pipe.o ser-tcp.o"
+SER_HARDWIRE="ser-unix.o ser-pipe.o ser-tcp.o ser-un.o"
 case ${host} in
   *go32* ) SER_HARDWIRE=ser-go32.o ;;
   *djgpp* ) SER_HARDWIRE=ser-go32.o ;;
diff -urN gdb-6.0.orig/gdb/configure.in gdb-6.0/gdb/configure.in
--- gdb-6.0.orig/gdb/configure.in	2004-03-02 18:00:01.000000000 +0200
+++ gdb-6.0/gdb/configure.in	2004-03-02 18:02:34.000000000 +0200
@@ -1062,7 +1062,7 @@
 
 
 dnl Figure out which of the many generic ser-*.c files the _host_ supports.
-SER_HARDWIRE="ser-unix.o ser-pipe.o ser-tcp.o"
+SER_HARDWIRE="ser-unix.o ser-pipe.o ser-tcp.o ser-un.o"
 case ${host} in
   *go32* ) SER_HARDWIRE=ser-go32.o ;;
   *djgpp* ) SER_HARDWIRE=ser-go32.o ;;
diff -urN gdb-6.0.orig/gdb/Makefile.in gdb-6.0/gdb/Makefile.in
--- gdb-6.0.orig/gdb/Makefile.in	2004-03-02 18:00:01.000000000 +0200
+++ gdb-6.0/gdb/Makefile.in	2004-03-02 18:02:10.000000000 +0200
@@ -1288,7 +1288,7 @@
 	remote-vx.c \
 	rs6000-nat.c rs6000-tdep.c \
 	s390-tdep.c s390-nat.c \
-	ser-go32.c ser-pipe.c ser-tcp.c \
+	ser-go32.c ser-pipe.c ser-tcp.c ser-un.c\
 	sh-tdep.c shnbsd-tdep.c shnbsd-nat.c \
 	solib.c solib-irix.c solib-svr4.c solib-sunos.c sparc-linux-nat.c \
 	sparc-nat.c \
@@ -2213,6 +2213,7 @@
 ser-pipe.o: ser-pipe.c $(defs_h) $(serial_h) $(ser_unix_h) $(gdb_vfork_h) \
 	$(gdb_string_h)
 ser-tcp.o: ser-tcp.c $(defs_h) $(serial_h) $(ser_unix_h) $(gdb_string_h)
+ser-un.o: ser-un.c $(defs_h) $(serial_h) $(ser_unix_h) $(gdb_string_h)
 ser-unix.o: ser-unix.c $(defs_h) $(serial_h) $(ser_unix_h) $(terminal_h) \
 	$(gdb_string_h) $(event_loop_h)
 sh3-rom.o: sh3-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
diff -urN gdb-6.0.orig/gdb/serial.c gdb-6.0/gdb/serial.c
--- gdb-6.0.orig/gdb/serial.c	2004-03-02 18:00:07.000000000 +0200
+++ gdb-6.0/gdb/serial.c	2004-03-02 18:03:36.000000000 +0200
@@ -184,6 +184,8 @@
 
   if (strcmp (name, "pc") == 0)
     ops = serial_interface_lookup ("pc");
+  else if (strncmp (name, "unix", 4) == 0)
+    ops = serial_interface_lookup ("un");
   else if (strchr (name, ':'))
     ops = serial_interface_lookup ("tcp");
   else if (strncmp (name, "lpt", 3) == 0)
diff -urN gdb-6.0.orig/gdb/ser-un.c gdb-6.0/gdb/ser-un.c
--- gdb-6.0.orig/gdb/ser-un.c	1970-01-01 03:00:00.000000000 +0300
+++ gdb-6.0/gdb/ser-un.c	2004-03-02 18:01:27.000000000 +0200
@@ -0,0 +1,199 @@
+/* Serial interface for raw TCP connections on Un*x like systems
+   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001
+   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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "serial.h"
+#include "ser-unix.h"
+
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>  /* For FIONBIO. */
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>  /* For FIONBIO. */
+#endif
+
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <signal.h>
+#include "gdb_string.h"
+
+static int un_net_open (struct serial *scb, const char *name);
+static void un_net_close (struct serial *scb);
+extern int (*ui_loop_hook) (int);
+void _initialize_ser_un (void);
+
+/* seconds to wait for connect */
+#define TIMEOUT 15
+/* how many times per second to poll ui_loop_hook */
+#define POLL_INTERVAL 2
+
+/* Open a tcp socket */
+
+static int
+un_net_open (struct serial *scb, const char *name)
+{
+  char hostname[100];
+  int n, tmp;
+  struct sockaddr_un sockaddr;
+
+  if (strncmp (name, "unix:", 5) == 0) {
+       name = name + 5;
+  } else {
+       return -1;
+  }
+
+  tmp = min (strlen(name), (int) sizeof hostname - 1);
+  strncpy (hostname, name, tmp);	/* Don't want colon */
+  hostname[tmp] = '\000';	/* Tie off host name */
+
+  /* default hostname is localhost */
+  if (!hostname[0])
+    strcpy (hostname, "localhost");
+
+  scb->fd = socket (PF_UNIX, SOCK_STREAM, 0);
+
+  if (scb->fd < 0)
+    return -1;
+  
+  sockaddr.sun_family = PF_UNIX;
+  strncpy(sockaddr.sun_path, hostname, tmp);
+
+  /* set socket nonblocking */
+  tmp = 1;
+  ioctl (scb->fd, FIONBIO, &tmp);
+
+  /* Use Non-blocking connect.  connect() will return 0 if connected already. */
+  n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
+
+  if (n < 0 && errno != EINPROGRESS)
+    {
+      un_net_close (scb);
+      return -1;
+    }
+
+  if (n)
+    {
+      /* looks like we need to wait for the connect */
+      struct timeval t;
+      fd_set rset, wset;
+      int polls = 0;
+      FD_ZERO (&rset);
+
+      do 
+	{
+	  /* While we wait for the connect to complete 
+	     poll the UI so it can update or the user can 
+	     interrupt. */
+	  if (ui_loop_hook)
+	    {
+	      if (ui_loop_hook (0))
+		{
+		  errno = EINTR;
+		  un_net_close (scb);
+		  return -1;
+		}
+	    }
+	  
+	  FD_SET (scb->fd, &rset);
+	  wset = rset;
+	  t.tv_sec = 0;
+	  t.tv_usec = 1000000 / POLL_INTERVAL;
+	  
+	  n = select (scb->fd + 1, &rset, &wset, NULL, &t);
+	  polls++;
+	} 
+      while (n == 0 && polls <= TIMEOUT * POLL_INTERVAL);
+      if (n < 0 || polls > TIMEOUT * POLL_INTERVAL)
+	{
+	  if (polls > TIMEOUT * POLL_INTERVAL)
+	    errno = ETIMEDOUT;
+	  un_net_close (scb);
+	  return -1;
+	}
+    }
+
+  /* Got something.  Is it an error? */
+  {
+    int res, err, len;
+    len = sizeof(err);
+    res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, &err, &len);
+    if (res < 0 || err)
+      {
+	if (err)
+	  errno = err;
+	un_net_close (scb);
+	return -1;
+      }
+  } 
+
+  /* turn off nonblocking */
+  tmp = 0;
+  ioctl (scb->fd, FIONBIO, &tmp);
+
+  /* If we don't do this, then GDB simply exits
+     when the remote side dies.  */
+  signal (SIGPIPE, SIG_IGN);
+
+  return 0;
+}
+
+static void
+un_net_close (struct serial *scb)
+{
+  if (scb->fd < 0)
+    return;
+
+  close (scb->fd);
+  scb->fd = -1;
+}
+
+void
+_initialize_ser_un (void)
+{
+  struct serial_ops *ops = XMALLOC (struct serial_ops);
+  memset (ops, 0, sizeof (struct serial_ops));
+  ops->name = "un";
+  ops->next = 0;
+  ops->open = un_net_open;
+  ops->close = un_net_close;
+  ops->readchar = ser_unix_readchar;
+  ops->write = ser_unix_write;
+  ops->flush_output = ser_unix_nop_flush_output;
+  ops->flush_input = ser_unix_flush_input;
+  ops->send_break = ser_unix_nop_send_break;
+  ops->go_raw = ser_unix_nop_raw;
+  ops->get_tty_state = ser_unix_nop_get_tty_state;
+  ops->set_tty_state = ser_unix_nop_set_tty_state;
+  ops->print_tty_state = ser_unix_nop_print_tty_state;
+  ops->noflush_set_tty_state = ser_unix_nop_noflush_set_tty_state;
+  ops->setbaudrate = ser_unix_nop_setbaudrate;
+  ops->setstopbits = ser_unix_nop_setstopbits;
+  ops->drain_output = ser_unix_nop_drain_output;
+  ops->async = ser_unix_async;
+  serial_add_interface (ops);
+}

type 
(gdb) target remote unix:/path/to/socket
to connect to remote

-- 
Zhenja Kaluta                                            ICQ 74596027
GnuPG FingerPrint: B86C B548 7CC4 B58F 0CA3  856E 7EE8 52DE E6B7 8725

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]