public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
From: scox@sourceware.org
To: archer-commits@sourceware.org
Subject: [SCM]  scox/globalstate: Add initial multiple client support.
Date: Fri, 25 Sep 2015 02:59:00 -0000	[thread overview]
Message-ID: <20150925025924.128650.qmail@sourceware.org> (raw)

The branch, scox/globalstate has been updated
       via  589dd9c8abac87fa8306733f9e6b56af97e739fb (commit)
      from  53b72aacff3f6171dec3dada5943526912940299 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 589dd9c8abac87fa8306733f9e6b56af97e739fb
Author: Stan Cox <scox@redhat.com>
Date:   Thu Sep 24 22:57:27 2015 -0400

    Add initial multiple client support.
    
    * event-loop.c (delete_file_handler): Add delete_client_state.
    * mem-break.c (has_client_breakpoint_at): New.
    * remote-utils.c (get_listen_desc):  New.
    * server.c (get_client_state, set_client_state)
    * server.h (last_status, last_ptid, current_thread)

-----------------------------------------------------------------------

Summary of changes:
 gdb/gdbserver/ChangeLog                   |   30 ++
 gdb/gdbserver/event-loop.c                |   43 ++
 gdb/gdbserver/mem-break.c                 |   30 ++
 gdb/gdbserver/mem-break.h                 |    4 +
 gdb/gdbserver/remote-utils.c              |   70 ++--
 gdb/gdbserver/remote-utils.h              |    3 +-
 gdb/gdbserver/server.c                    |  610 +++++++++++++++++++++++++++--
 gdb/gdbserver/server.h                    |   52 +++-
 gdb/testsuite/gdb.server/multi-client.exp |  166 ++++++++
 9 files changed, 948 insertions(+), 60 deletions(-)
 create mode 100644 gdb/testsuite/gdb.server/multi-client.exp

First 500 lines of diff:
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index cf961e2..6c80e10 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,33 @@
+2015-09-24  Stan Cox  <scox@redhat.com>
+
+	* server.c (get_client_state, set_client_state)
+	(delete_client_breakpoint, free_client_state, add_client_by_pid)
+	(add_client_by_exe, get_first_client_fd, have_multiple_clients)
+	(delete_client_state, add_client_breakpoint)  New for managing
+	client/server structures.
+	(pending_types, get_pack_type, resolve_waiter, setup_multiplexing)
+	(setup_multiplexing, do_multiplexing)  New for managing run state
+	of clients.
+	(start_inferior): Add client to list.
+	(handle_monitor_command):  Add 'client status'
+	(process_serial_event): Manage multiple client connections.  Call
+	(setup,do)_multiplexing.
+
+	* server.h (last_status, last_ptid, current_thread)
+	(exit_requested): Add union as access macro alternative
+	(client_breakpoint):  New struct.
+	(file_desc, executable, packet_type, last_packet_type, pending):  New.
+
+	* event-loop.c (delete_file_handler): Add delete_client_state.
+	(handle_file_event): Reset file descriptor for multiple clients.
+	(wait_for_event): Handle additional client connections.
+
+	* mem-break.c (has_client_breakpoint_at): New.
+
+	* remote-utils.c (get_listen_desc):  New.
+	(handle_accept_event):  Unset noack_mode.
+	(write_prim, write, read_prim, readchar, getpkt):  Add file desc parm.
+
 2015-09-12  Stan Cox  <scox@redhat.com>
 
 	* gdbthread.h (last_status): Rename last_waitstatus to avoid conflict
diff --git a/gdb/gdbserver/event-loop.c b/gdb/gdbserver/event-loop.c
index dd07093..3724cd7 100644
--- a/gdb/gdbserver/event-loop.c
+++ b/gdb/gdbserver/event-loop.c
@@ -385,6 +385,8 @@ delete_file_handler (gdb_fildes_t fd)
 	;
       prev_ptr->next_file = file_ptr->next_file;
     }
+
+  delete_client_state (fd);
   free (file_ptr);
 }
 
@@ -425,6 +427,9 @@ handle_file_event (gdb_fildes_t event_file_desc)
 	  /* If there was a match, then call the handler.  */
 	  if (mask != 0)
 	    {
+	      /* Don't change client states if we have multiple clients */
+	      if (have_multiple_clients ())
+		set_client_state (file_ptr->fd);
 	      if ((*file_ptr->proc) (file_ptr->error,
 				     file_ptr->client_data) < 0)
 		return -1;
@@ -465,6 +470,38 @@ wait_for_event (void)
   file_handler *file_ptr;
   int num_found = 0;
 
+  /* Do we have another client? */
+  fd_set conn_fd_set;
+  struct timeval timeout;
+  FD_ZERO(&conn_fd_set);
+  FD_SET(get_listen_desc(),&conn_fd_set);
+  timeout.tv_sec = 0;
+  timeout.tv_usec = 10;
+  num_found = select (FD_SETSIZE, &conn_fd_set, NULL, NULL, &timeout);
+  if (debug_threads > 1)
+    fprintf (stderr,"%s select fd=%d found=%d\n",__FUNCTION__,get_listen_desc(),num_found);
+  if (num_found > 0)
+    {
+    int i;
+      for (i = 1; i < FD_SETSIZE; ++i)
+	if (FD_ISSET (i, &conn_fd_set))
+	  {
+	    if (i == get_listen_desc())
+	      {
+		int handle_accept_event (int, gdb_client_data);
+		if (debug_threads > 1)
+		  fprintf (stderr,"%s in select idx %d\n",__FUNCTION__,i);
+		/* instead of using gdb_event just setup the connection "by hand" */
+		handle_accept_event (0, NULL);
+		add_file_handler (get_remote_desc(), handle_serial_event, get_client_state());
+	      }
+	    else
+	      if (debug_threads > 1)
+		fprintf (stderr,"%s data arrived on existing connection %d fd=%d\n", __FUNCTION__, i,get_listen_desc());
+	  }
+    }
+  /* */
+
   /* Make sure all output is done before getting another event.  */
   fflush (stdout);
   fflush (stderr);
@@ -520,8 +557,14 @@ wait_for_event (void)
 
       if (file_ptr->ready_mask == 0)
 	{
+	  int handle_accept_event (int err, gdb_client_data client_data);
 	  gdb_event *file_event_ptr = create_file_event (file_ptr->fd);
 
+	  if (debug_threads > 1)
+	    {
+	      fprintf (stderr,"%s #fds=%d\n",__FUNCTION__,gdb_notifier.num_fds);
+	      fprintf(stderr,"%s create_file_event for %d %#lx %#lx %#lx %#lx\n",__FUNCTION__,file_event_ptr->fd,(long unsigned int)file_ptr->proc,(long unsigned int)handle_file_event,(long unsigned int)handle_serial_event,(long unsigned int)handle_accept_event);
+	    }
 	  QUEUE_enque (gdb_event_p, event_queue, file_event_ptr);
 	}
       file_ptr->ready_mask = mask;
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index 9356741..138e8e0 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -293,6 +293,36 @@ find_raw_breakpoint_at (CORE_ADDR addr, enum raw_bkpt_type type, int size)
   return NULL;
 }
 
+/* Is there a low-level breakpoint at address ADDR? */
+
+int
+has_client_breakpoint_at (CORE_ADDR addr)
+{
+  client_state *cs = get_client_state ();
+
+  struct client_breakpoint *cb;
+  if (debug_threads)
+    debug_printf ("%s:%d fd=%d addr=%#lx\n", __FUNCTION__, __LINE__, cs->file_desc, (long unsigned)addr);
+  for (cb = cs->client_breakpoints; cb != NULL; cb = cb->next)
+    if (debug_threads)
+      debug_printf ("%s:%d %d breakpoint at %#lx\n", __FUNCTION__, __LINE__, cs->file_desc, (long unsigned)cb->addr);
+
+  //  for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
+    {
+      //      if (addr >= bp->pc && addr <= bp->pc + 8 && cs->ss->last_status.kind == TARGET_WAITKIND_STOPPED
+      //	  && cs->ss->last_status.value.sig == GDB_SIGNAL_TRAP)
+	  for (cb = cs->client_breakpoints; cb != NULL; cb = cb->next)
+	    // TODO improve this; pc might be one insn ahead of break. 
+	    {
+	      debug_printf ("%s:%d addr=%#lx pb->pc %#lx in range? %d\n", __FUNCTION__, __LINE__, (long unsigned) addr, (long unsigned)cb->addr, addr >= cb->addr && addr <= cb->addr + 8);
+	      if (addr >= cb->addr && addr <= cb->addr + 8)
+		return 1;
+	    }
+    }
+  return 0;
+}
+
+
 /* See mem-break.h.  */
 
 int
diff --git a/gdb/gdbserver/mem-break.h b/gdb/gdbserver/mem-break.h
index b5a3208..9f737d0 100644
--- a/gdb/gdbserver/mem-break.h
+++ b/gdb/gdbserver/mem-break.h
@@ -245,6 +245,10 @@ void uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc);
 
 void reinsert_fast_tracepoint_jumps_at (CORE_ADDR where);
 
+/* Does a client have a breakpoint at addr? */
+
+int has_client_breakpoint_at (CORE_ADDR addr);
+
 /* Insert a memory breakpoint.  */
 
 int insert_memory_breakpoint (struct raw_breakpoint *bp);
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 67268ea..d2b3b85 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -88,7 +88,7 @@ enum {
    Either NOT_SCHEDULED or the callback id.  */
 static int readchar_callback = NOT_SCHEDULED;
 
-static int readchar (void);
+static int readchar (gdb_fildes_t);
 static void reset_readchar (void);
 static void reschedule (void);
 
@@ -136,6 +136,12 @@ set_remote_desc (gdb_fildes_t fd)
 }
 
 int
+get_listen_desc ()
+{
+  return listen_desc;
+}
+
+int
 gdb_connected (void)
 {
   return remote_desc != INVALID_DESCRIPTOR;
@@ -163,7 +169,7 @@ enable_async_notification (int fd)
 #endif
 }
 
-static int
+int
 handle_accept_event (int err, gdb_client_data client_data)
 {
   struct sockaddr_in sockaddr;
@@ -172,11 +178,14 @@ handle_accept_event (int err, gdb_client_data client_data)
   if (debug_threads)
     debug_printf ("handling possible accept event\n");
 
+  noack_mode = 0;
   tmp = sizeof (sockaddr);
   remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &tmp);
   if (remote_desc == -1)
     perror_with_name ("Accept failed");
 
+  set_client_state (remote_desc);
+
   /* Enable TCP keep alive process. */
   tmp = 1;
   setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE,
@@ -193,7 +202,8 @@ handle_accept_event (int err, gdb_client_data client_data)
 				   exits when the remote side dies.  */
 #endif
 
-  if (run_once)
+  /* TODO check this */
+  if (0 && run_once)
     {
 #ifndef USE_WIN32API
       close (listen_desc);		/* No longer need this */
@@ -204,7 +214,8 @@ handle_accept_event (int err, gdb_client_data client_data)
 
   /* Even if !RUN_ONCE no longer notice new connections.  Still keep the
      descriptor open for add_file_handler to wait for a new connection.  */
-  delete_file_handler (listen_desc);
+  // TODO check this
+  //  delete_file_handler (listen_desc);
 
   /* Convert IP address to string.  */
   fprintf (stderr, "Remote debugging from host %s\n",
@@ -601,12 +612,12 @@ read_ptid (char *buf, char **obuf)
    This may return less than COUNT.  */
 
 static int
-write_prim (const void *buf, int count)
+write_prim (gdb_fildes_t fd, const void *buf, int count)
 {
   if (remote_connection_is_stdio ())
     return write (fileno (stdout), buf, count);
   else
-    return write (remote_desc, buf, count);
+    return write (fd, buf, count);
 }
 
 /* Read COUNT bytes from the client and store in BUF.
@@ -614,12 +625,12 @@ write_prim (const void *buf, int count)
    This may return less than COUNT.  */
 
 static int
-read_prim (void *buf, int count)
+read_prim (gdb_fildes_t fd, void *buf, int count)
 {
   if (remote_connection_is_stdio ())
     return read (fileno (stdin), buf, count);
   else
-    return read (remote_desc, buf, count);
+    return read (fd, buf, count);
 }
 
 /* Send a packet to the remote machine, with error checking.
@@ -634,6 +645,7 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
   char *buf2;
   char *p;
   int cc;
+  client_state *cs = get_client_state();
 
   buf2 = xmalloc (strlen ("$") + cnt + strlen ("#nn") + 1);
 
@@ -659,7 +671,7 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
 
   do
     {
-      if (write_prim (buf2, p - buf2) != p - buf2)
+      if (write_prim (cs->file_desc, buf2, p - buf2) != p - buf2)
 	{
 	  perror ("putpkt(write)");
 	  free (buf2);
@@ -672,9 +684,9 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
 	  if (remote_debug)
 	    {
 	      if (is_notif)
-		fprintf (stderr, "putpkt (\"%s\"); [notif]\n", buf2);
+		fprintf (stderr, "putpkt/%d (\"%s\"); [notif]\n", cs->file_desc, buf2);
 	      else
-		fprintf (stderr, "putpkt (\"%s\"); [noack mode]\n", buf2);
+		fprintf (stderr, "putpkt/%d (\"%s\"); [noack mode]\n", cs->file_desc, buf2);
 	      fflush (stderr);
 	    }
 	  break;
@@ -682,11 +694,11 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
 
       if (remote_debug)
 	{
-	  fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2);
+	  fprintf (stderr, "putpkt/%d (\"%s\"); [looking for ack]\n", cs->file_desc, buf2);
 	  fflush (stderr);
 	}
 
-      cc = readchar ();
+      cc = readchar (cs->file_desc);
 
       if (cc < 0)
 	{
@@ -754,7 +766,7 @@ input_interrupt (int unused)
       int cc;
       char c = 0;
 
-      cc = read_prim (&c, 1);
+      cc = read_prim (remote_desc, &c, 1);
 
       if (cc == 0)
 	{
@@ -877,13 +889,13 @@ initialize_async_io (void)
 /* Returns next char from remote GDB.  -1 if error.  */
 
 static int
-readchar (void)
+readchar (gdb_fildes_t fd)
 {
   int ch;
 
   if (readchar_bufcnt == 0)
     {
-      readchar_bufcnt = read_prim (readchar_buf, sizeof (readchar_buf));
+      readchar_bufcnt = read_prim (fd, readchar_buf, sizeof (readchar_buf));
 
       if (readchar_bufcnt <= 0)
 	{
@@ -949,7 +961,7 @@ reschedule (void)
    and store it in BUF.  Returns length of packet, or negative if error. */
 
 int
-getpkt (char *buf)
+getpkt (gdb_fildes_t fd, char *buf)
 {
   char *bp;
   unsigned char csum, c1, c2;
@@ -961,7 +973,7 @@ getpkt (char *buf)
 
       while (1)
 	{
-	  c = readchar ();
+	  c = readchar (fd);
 	  if (c == '$')
 	    break;
 	  if (remote_debug)
@@ -977,7 +989,7 @@ getpkt (char *buf)
       bp = buf;
       while (1)
 	{
-	  c = readchar ();
+	  c = readchar (fd);
 	  if (c < 0)
 	    return -1;
 	  if (c == '#')
@@ -987,8 +999,8 @@ getpkt (char *buf)
 	}
       *bp = 0;
 
-      c1 = fromhex (readchar ());
-      c2 = fromhex (readchar ());
+      c1 = fromhex (readchar (fd));
+      c2 = fromhex (readchar (fd));
 
       if (csum == (c1 << 4) + c2)
 	break;
@@ -1005,7 +1017,7 @@ getpkt (char *buf)
 
       fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
 	       (c1 << 4) + c2, csum, buf);
-      if (write_prim ("-", 1) != 1)
+      if (write_prim (fd, "-", 1) != 1)
 	return -1;
     }
 
@@ -1013,11 +1025,11 @@ getpkt (char *buf)
     {
       if (remote_debug)
 	{
-	  fprintf (stderr, "getpkt (\"%s\");  [sending ack] \n", buf);
+	  fprintf (stderr, "getpkt/%d (\"%s\");  [sending ack] \n", fd, buf);
 	  fflush (stderr);
 	}
 
-      if (write_prim ("+", 1) != 1)
+      if (write_prim (fd, "+", 1) != 1)
 	return -1;
 
       if (remote_debug)
@@ -1030,7 +1042,7 @@ getpkt (char *buf)
     {
       if (remote_debug)
 	{
-	  fprintf (stderr, "getpkt (\"%s\");  [no ack sent] \n", buf);
+	  fprintf (stderr, "getpkt/%d (\"%s\");  [no ack sent] \n", fd, buf);
 	  fflush (stderr);
 	}
     }
@@ -1451,7 +1463,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
     return -1;
 
   /* FIXME:  Eventually add buffer overflow checking (to getpkt?)  */
-  len = getpkt (own_buf);
+  len = getpkt (remote_desc, own_buf);
   if (len < 0)
     return -1;
 
@@ -1475,7 +1487,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
       free (mem_buffer);
       if (putpkt (own_buf) < 0)
 	return -1;
-      len = getpkt (own_buf);
+      len = getpkt (remote_desc, own_buf);
       if (len < 0)
 	return -1;
     }
@@ -1534,7 +1546,7 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
     return -1;
 
   /* FIXME:  Eventually add buffer overflow checking (to getpkt?)  */
-  len = getpkt (own_buf);
+  len = getpkt (remote_desc, own_buf);
   if (len < 0)
     return -1;
 
@@ -1577,7 +1589,7 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
       free (mem_buffer);
       if (putpkt (own_buf) < 0)
 	return -1;
-      len = getpkt (own_buf);
+      len = getpkt (remote_desc, own_buf);
       if (len < 0)
 	return -1;
     }
diff --git a/gdb/gdbserver/remote-utils.h b/gdb/gdbserver/remote-utils.h
index 2a1c62f..32f0b52 100644
--- a/gdb/gdbserver/remote-utils.h
+++ b/gdb/gdbserver/remote-utils.h
@@ -25,6 +25,7 @@ extern int transport_is_reliable;
 
 int get_remote_desc (void);
 void set_remote_desc (gdb_fildes_t);
+int get_listen_desc (void);
 
 int gdb_connected (void);
 
@@ -37,7 +38,7 @@ char *write_ptid (char *buf, ptid_t ptid);
 int putpkt (char *buf);
 int putpkt_binary (char *buf, int len);
 int putpkt_notif (char *buf);
-int getpkt (char *buf);
+int getpkt (gdb_fildes_t,char *buf);
 void remote_prepare (char *name);
 void remote_open (char *name);
 void remote_close (void);
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 9838a6f..07828c2 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -83,33 +83,520 @@ DEFINE_QUEUE_P (notif_event_p);
 
 static struct client_states  client_states;
 
+static void handle_status (char *);
+
+
+/* Return the current client state */
+
+extern inline client_state*
+get_client_state (void)
+{
+  return client_states.current_cs;
+}
+
 
 /* Add a new client state for fd or return if found */
 
 client_state *
 set_client_state (gdb_fildes_t fd)
 {
-  if (client_states.first == NULL)
+/* States:
+ * fd = -1 add initial client state
+ * fd =  F add client state for fd F
+ */
+
+  client_state *csidx;
+
+  /* add/return initial client state */


hooks/post-receive
--
Repository for Project Archer.


                 reply	other threads:[~2015-09-25  2:59 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150925025924.128650.qmail@sourceware.org \
    --to=scox@sourceware.org \
    --cc=archer-commits@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).