This is the mail archive of the gdb-patches@sourceware.org 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]

[PATCH] Use a shell command as a socket for gdbserver


This brings feature parity with gdb in this regard.

This can be used to do gdbserver over unix socket (without redirecting
the inferior stdio to /dev/null):

    $ gdbserver '|socat STDIO UNIX-LISTEN:foo.sock' ./foo

and in gdb:

    (gdb) target remote |socat STDIO UNIX:foo.sock

Altneratively, we can initiate a connection to a remote server:

    $ gdbserver '|socat STDIO TCP:gdb.example.com:9000' ./foo

gdb/gdbserver/ChangeLog:

        * remote-utils.c: add support for using a shell command stdio as COMM
        * remote.c: add documentation about this feature
---
 gdb/gdbserver/remote-utils.c | 63 ++++++++++++++++++++++++++++++++++++++++++++
 gdb/gdbserver/server.c       |  3 ++-
 2 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 1de86be..6d88968 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -58,6 +58,8 @@
 #endif
 #include <sys/stat.h>
 
+#include "gdb_wait.h"
+
 #if USE_WIN32API
 #include <winsock2.h>
 #endif
@@ -239,6 +241,14 @@ remote_prepare (char *name)
       return;
     }
 
+#ifndef USE_WIN32API
+  if (name[0] == '|')
+    {
+      transport_is_reliable = 1;
+      return;
+    }
+#endif
+
   port_str = strchr (name, ':');
   if (port_str == NULL)
     {
@@ -280,6 +290,48 @@ remote_prepare (char *name)
   transport_is_reliable = 1;
 }
 
+#ifndef USE_WIN32API
+static int open_shell_command(char* command)
+{
+  int sockets[2];
+  int res;
+  pid_t child, pid;
+
+  res = socketpair(AF_LOCAL, SOCK_STREAM, 0, sockets);
+  if (res < 0)
+    error ("Could not get socketpair.");
+  child = fork();
+  if (child < 0)
+    {
+      error ("Could not fork.");
+    }
+  else if (child == 0)
+    {
+      if (close (sockets[0]) < 0)
+	exit (1);
+      if (dup2 (sockets[1], 0) < 0 || dup2 (sockets[1], 1) < 0)
+	exit (1);
+      res = fork ();
+      if (res < 0)
+	exit (1);
+      if (res != 0)
+	exit (0);
+      execl ("/bin/sh", "sh", "-c", command, NULL);
+      exit (1);
+    }
+  else
+    {
+      signal (SIGPIPE, SIG_IGN);
+      while ((pid = waitpid (child, NULL, 0)) < 0 && errno == EINTR);
+      if (pid < 0)
+	error ("Could not wait for child.");
+      close (sockets[1]);
+      return sockets[0];
+     }
+  return -1;
+}
+#endif
+
 /* Open a connection to a remote debugger.
    NAME is the filename used for communication.  */
 
@@ -288,6 +340,17 @@ remote_open (char *name)
 {
   char *port_str;
 
+#ifndef USE_WIN32API
+  if (name[0] == '|')
+    {
+      fprintf (stderr, "Remote debugging using shell command\n");
+      remote_desc = open_shell_command (name + 1);
+      enable_async_notification (remote_desc);
+      add_file_handler (remote_desc, handle_serial_event, NULL);
+      return;
+    }
+#endif
+
   port_str = strchr (name, ':');
 #ifdef USE_WIN32API
   if (port_str == NULL)
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index d2e20d9..9ed4049 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -3036,7 +3036,8 @@ gdbserver_usage (FILE *stream)
 	   "\tgdbserver [OPTIONS] --attach COMM PID\n"
 	   "\tgdbserver [OPTIONS] --multi COMM\n"
 	   "\n"
-	   "COMM may either be a tty device (for serial debugging),\n"
+	   "COMM may be a tty device (for serial debugging),\n"
+	   "'|some shell command' to use stdin/stdout of a given shell command,\n"
 	   "HOST:PORT to listen for a TCP connection, or '-' or 'stdio' to use \n"
 	   "stdin/stdout of gdbserver.\n"
 	   "PROG is the executable program.  ARGS are arguments passed to inferior.\n"
-- 
2.1.4


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