public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  scox/dyninst: Add initial version of a multiple client gdbserver test.
@ 2015-08-25 14:13 scox
  0 siblings, 0 replies; only message in thread
From: scox @ 2015-08-25 14:13 UTC (permalink / raw)
  To: archer-commits

The branch, scox/dyninst has been updated
       via  a8a28945db8a7c3323bd15b89f4eb66bd71d72bf (commit)
      from  fabed36970d646da35ab5d0d1c4ab954356266b8 (commit)

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

- Log -----------------------------------------------------------------
commit a8a28945db8a7c3323bd15b89f4eb66bd71d72bf
Author: Stan Cox <scox@redhat.com>
Date:   Tue Aug 25 10:00:44 2015 -0400

    Add initial version of a multiple client gdbserver test.
    
    * server.c (add_client_by_pid, add_client_by_exe, get_first_client_fd):
      Renamed from add_client_state, attach_client_state, count_client_state
      (have_multiple_clients): New
      (setup_multiplexing, do_multiplexing):  Moved from process_serial_event.
    * testsuite/gdb.server/multi-client.exp:  New.

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

Summary of changes:
 gdb/gdbserver/dyninst-low.cc              |    4 +-
 gdb/gdbserver/event-loop.c                |    2 +-
 gdb/gdbserver/remote-utils.c              |    2 +-
 gdb/gdbserver/server.c                    |  389 +++++++++++++++--------------
 gdb/gdbserver/server.h                    |    3 +-
 gdb/testsuite/gdb.server/multi-client.exp |  132 ++++++++++
 6 files changed, 344 insertions(+), 188 deletions(-)
 create mode 100644 gdb/testsuite/gdb.server/multi-client.exp

First 500 lines of diff:
diff --git a/gdb/gdbserver/dyninst-low.cc b/gdb/gdbserver/dyninst-low.cc
index 8f3273a..3686231 100644
--- a/gdb/gdbserver/dyninst-low.cc
+++ b/gdb/gdbserver/dyninst-low.cc
@@ -55,7 +55,7 @@ extern "C"
 
 
 #define DYNERRMSG(errstr,args...)						\
-      fprintf (stderr, "%s %s " errstr "\n", __FUNCTION__, getLastErrorMsg(), ##args);
+      error ("%s " errstr , getLastErrorMsg(), ##args);
 #define DYNERR(errstr,args...)						\
   fprintf (stderr, "%s " errstr "\n", __FUNCTION__, ##args);
 #define DEBUG_ENTER() if (debug_threads) debug_enter()
@@ -745,7 +745,7 @@ dyninst_create_inferior (char *program, char **allargs)
 
   Process::ptr dyninst_process = Process::createProcess(exec, args);
   if (dyninst_process == Process::ptr())
-    DYNERRMSG ("No such file: %s\n", exec.c_str());
+    DYNERRMSG ("stdin/stdout redirected\nCannot exec %s: No such file or directory\nNo program to debug", exec.c_str());
 
   myregisterCB(EventType::Bootstrap, signal_handler);
   myregisterCB(EventType::Breakpoint, breakpoint_handler);
diff --git a/gdb/gdbserver/event-loop.c b/gdb/gdbserver/event-loop.c
index 90c9767..c5ec296 100644
--- a/gdb/gdbserver/event-loop.c
+++ b/gdb/gdbserver/event-loop.c
@@ -436,7 +436,7 @@ handle_file_event (gdb_fildes_t event_file_desc)
 	  if (mask != 0)
 	    {
 	      /* Don't change client states if we have multiple clients */
-	      if (count_client_state (NULL) > 1)
+	      if (have_multiple_clients ())
 		set_client_state (file_ptr->fd);
 	      if ((*file_ptr->proc) (file_ptr->error,
 				     file_ptr->client_data) < 0)
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 2807de7..e61fde4 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -1046,7 +1046,7 @@ getpkt (gdb_fildes_t fd, char *buf)
     {
       if (remote_debug)
 	{
-	  fprintf (stderr, "getpkt/%d(\"%s\");  [sending ack] \n", fd, buf);
+	  fprintf (stderr, "getpkt/%d (\"%s\");  [sending ack] \n", fd, buf);
 	  fflush (stderr);
 	}
 
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 05f7dff..072b87c 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -128,16 +128,12 @@ static void free_client_state (client_state *cs)
 {
   /* TODO keep reference count and delete when 0 */
   client_state *csi;
-  int another_ss_client = 0;
   for (csi = client_states.first; csi != NULL; csi = csi->next)
     {
       if (csi->executable && csi != cs && csi->ss == cs->ss)
-	{
-	  another_ss_client = 1;
-	  break;
-	}
+	break;
     }
-  if (! another_ss_client)
+  if (csi == NULL)
     free_server_state (cs->ss);
   if (cs->executable)
     xfree (cs->executable);
@@ -165,10 +161,11 @@ dump_client_state ()
     }
 }
 
-/* Are we attaching to a process we have already encountered? */
 
-int
-attach_client_state (client_state *cs, int pid)
+/* Add another client to the 1 server -> N client list. */
+
+client_state *
+add_client_by_pid (client_state *cs, int pid)
 {
   client_state *matched_cs;
 
@@ -181,10 +178,40 @@ attach_client_state (client_state *cs, int pid)
 	  cs->executable = matched_cs->executable;
 	  free_server_state (cs->ss);
 	  cs->ss = matched_cs->ss;		/* reuse the matched server state */
-	  return 1;
+	  cs->ss->attach_count += 1;
+	  return cs;
 	}
     }
-  return 0;
+  return NULL;
+}
+
+
+client_state *
+add_client_by_exe (client_state *cs, char *executable)
+{
+  client_state *csi;
+  char *new_executable;
+  dump_client_state();
+
+  for (csi = client_states.first; csi != NULL; csi = csi->next)
+    {
+      if (csi->executable && strcmp (csi->executable, executable) == 0 && csi != cs)
+	  break;
+    }
+
+  new_executable = xmalloc (strlen (executable) + 1);
+  strcpy (new_executable, executable);
+  cs->executable = new_executable;
+
+  if (csi != NULL)
+    {
+      free_server_state (cs->ss);		/* reuse the matched server state */
+      cs->ss = csi->ss;
+      cs->ss->attach_count += 1;
+      return cs;
+    }
+
+  return NULL;
 }
 
 
@@ -206,7 +233,7 @@ set_client_state (gdb_fildes_t fd)
     {
       if (client_states.first == NULL)
 	{
-	  client_states.first= new_client_state ();
+	  client_states.first = new_client_state ();
 	  client_states.first->ss = new_server_state ();
 	  client_states.first->file_desc = fd;
 	}
@@ -263,29 +290,40 @@ set_client_state (gdb_fildes_t fd)
   client_states.current_fd = fd;
   client_states.current_cs = new_csidx;
   csidx->next = new_csidx;
-  if (debug_threads)
-    debug_printf ("%s:%d Called returned fd=%d current=%d\n", __FUNCTION__, __LINE__, fd, client_states.current_fd);
   return new_csidx;
 }
 
 
-/* Return the client state count and optionally return the last client's fd */
+/* Return the client state count */
 
-int
-count_client_state (gdb_fildes_t *fdp)
+gdb_fildes_t
+get_first_client_fd ()
 {
   client_state *cs;
-  int n_client_states = 0;
   for (cs = client_states.first; cs != NULL; cs = cs->next)
     {
       if (cs->file_desc > 0 && cs->executable != NULL)
 	{
-	  n_client_states += 1;
-	  if (fdp)
-	    *fdp = cs->file_desc;
+	  return cs->file_desc;
 	}
     }
-  return n_client_states;
+  return 0;
+}
+
+
+/* Is there more than one client? */
+
+int
+have_multiple_clients ()
+{
+  client_state *cs;
+  int n_client_states= 0;
+  for (cs = client_states.first; cs != NULL; cs = cs->next)
+    {
+      if (cs->file_desc > 0 && cs->executable != NULL)
+	n_client_states += 1;
+    }
+  return n_client_states > 1;
 }
 
 
@@ -325,9 +363,8 @@ delete_client_state (gdb_fildes_t fd)
 
 
 void
-add_client_breakpoint(CORE_ADDR addr)
+add_client_breakpoint (client_state *cs, CORE_ADDR addr)
 {
-  client_state *cs = client_states.current_cs;
   struct client_breakpoint *cb;
   struct client_breakpoint *newcb;
   for (cb = cs->breakpoints; cb != NULL; cb = cb->next)
@@ -349,7 +386,7 @@ add_client_breakpoint(CORE_ADDR addr)
 }
 
 void
-delete_client_breakpoint(client_state *cs, CORE_ADDR addr)
+delete_client_breakpoint (client_state *cs, CORE_ADDR addr)
 {
   struct client_breakpoint *cb;
   struct client_breakpoint *previous_cb = NULL;
@@ -383,58 +420,6 @@ get_client_state (void)
  return client_states.current_cs;
 }
 
-/* Add another client to the 1 server -> N client list. */
-
-client_state *
-add_client_state (char *executable)
-{
-  client_state *cs;
-  char *new_executable;
-  int entry = 0;
-  client_state *matched_cs = NULL;
-  dump_client_state();
-  for (cs = client_states.first; cs != NULL; cs = cs->next)
-    {
-      if (debug_threads)
-	debug_printf ("%s:%d %s looking for %s entry %d for fd %d\n", __FUNCTION__, __LINE__, cs->executable, executable, entry++, cs->file_desc);
-    }
-
-  for (cs = client_states.first; cs != NULL; cs = cs->next)
-    {
-      if (cs->executable && strcmp (cs->executable, executable) == 0)
-	{
-	  matched_cs = cs;
-	  break;
-	}
-    }
-
-  /* TODO Is there a window where multiple clients are created by new_client_state but not yet setup by match_client_state? */
-  cs = set_client_state (client_states.current_fd);
-  new_executable = xmalloc (strlen (executable) + 1);
-  strcpy (new_executable, executable);
-  cs->executable = new_executable;
-
-  if (matched_cs && cs != matched_cs)
-    {
-      client_state *tcs = get_client_state();
-      client_state *next_cs = cs->next;
-      gdb_fildes_t file_desc = cs->file_desc;
-      free_server_state (cs->ss);		/* reuse the matched server state */
-      cs->ss = matched_cs->ss;
-      cs->ss->attach_count += 1;
-      cs->next = next_cs;
-      cs->file_desc = file_desc;
-      debug_printf ("%s current=%d returning %d\n", __FUNCTION__,tcs->file_desc,cs->file_desc);
-      return cs;
-    }
-  else
-    {
-      if (debug_threads)
-	debug_printf ("%s %s %d returning null\n", __FUNCTION__, cs->executable, cs->file_desc);
-    }
-
-  return NULL;
-}
 
 static void handle_status (char *);
 /*
@@ -488,7 +473,7 @@ normalize_packet (client_state *cs, int ignore_packet)
 	    ignored_packet = 1;
 	  }
 	else
-	  cs->normalized_packet= 'c';
+	  cs->normalized_packet = 'c';
       else if ((strncmp (cs->in_buf, "vCont;r", 7) == 0) || (strncmp (cs->in_buf, "vCont;s", 7) == 0))
 	if (ignore_packet)
 	  {
@@ -498,7 +483,7 @@ normalize_packet (client_state *cs, int ignore_packet)
 	    ignored_packet = 1;
 	  }
 	else
-	  cs->normalized_packet= 's';
+	  cs->normalized_packet = 's';
       else if (strncmp (cs->in_buf, "vRun", 4) == 0)
 	{
 	  if (ignore_packet)
@@ -510,6 +495,7 @@ normalize_packet (client_state *cs, int ignore_packet)
 	  else
 	    cs->normalized_packet = 'r';
 	}
+
       break;
 
     default:
@@ -529,6 +515,137 @@ normalize_packet (client_state *cs, int ignore_packet)
 }
 
 
+int
+setup_multiplexing (client_state *cs, char *ch)
+{ /* Handle pending type */
+  client_state *csidx = NULL;
+
+  for (csidx = client_states.first; csidx != NULL; csidx = csidx->next)
+    {
+      /* another client is attached to the cs process */
+      if (csidx->file_desc != -1 && csidx != cs && cs->ss == csidx->ss)
+	{
+	  if (debug_threads)
+	    debug_printf ("%s:%d csidx pending=%d packet=%d cs pending=%d packet=%d\n", __FUNCTION__, __LINE__, csidx->pending, csidx->normalized_packet, cs->pending, cs->normalized_packet);
+	  /* find this client's pending type */
+	  if (!csidx->pending)
+	    {
+	      if (cs->normalized_packet == 'c')
+		{
+		  cs->pending = pending_cont_waiter;
+		  if (cs->last_normalized_packet != 'r')
+		    csidx->pending = pending_waitee;
+
+		  if (debug_threads)
+		    debug_printf ("%s:%d pending check set %d %d\n", __FUNCTION__, __LINE__,csidx->file_desc,csidx->pending);
+		}
+	      else if (cs->normalized_packet == 's')
+		{
+		  cs->pending = pending_step_waiter;
+		  if (cs->last_normalized_packet != 'r')
+		    csidx->pending = pending_waitee;
+		  if (debug_threads)
+		    debug_printf ("%s:%d pending check set %d %d\n", __FUNCTION__, __LINE__,csidx->file_desc,csidx->pending);
+		}
+	    }
+	}
+    }
+  if (debug_threads)
+    debug_printf ("%s:%d pending check %d waiter=%d\n", __FUNCTION__, __LINE__,cs->file_desc,cs->pending);
+  if (cs->pending == pending_cont_waiter)
+    {
+      if (cs->last_normalized_packet != 'r')
+	return 0;
+      // A client is running a process that is already being run by another client
+      else
+	{
+	  *ch = '?';
+	  cs->pending = none_pending;
+	  cs->last_normalized_packet = '\0';
+	}
+    }
+  return 1;
+}
+
+
+int
+do_multiplexing (client_state *cs, char ch)
+{ /* Handle pending type */
+  client_state *csidx = NULL;
+
+  if (cs->normalized_packet != '\0')
+    cs->last_normalized_packet = cs->normalized_packet;
+  for (csidx = client_states.first; csidx != NULL; csidx = csidx->next)
+    {
+	if (cs->normalized_packet == 'c' && cs->pending == pending_waitee
+	    && csidx->pending == pending_cont_waiter)
+	  {
+	    /* TODO Don't assume only 2 clients connected to a process
+	       has waitee/waiter been resolved? */
+	    if (csidx->normalized_packet == 'c')
+	      {
+		char save_ch = ch;
+		client_state *save_cs = cs;
+		int waitee_has_bp, waiter_has_bp;
+		if (cs->ss->last_status.kind == TARGET_WAITKIND_EXITED)
+		  {
+		    waitee_has_bp = 1;
+		    waiter_has_bp = 1;
+		  }
+		else
+		  {
+		    waitee_has_bp = has_client_breakpoint_at ((*the_target->read_pc)(get_thread_regcache (cs->ss->current_thread, 1)));
+		    cs = set_client_state (csidx->file_desc);
+		    waiter_has_bp = has_client_breakpoint_at ((*the_target->read_pc)(get_thread_regcache (cs->ss->current_thread, 1)));
+		    if (debug_threads)
+		      debug_printf ("%s:%d pc=%#lx waitee=%d has bp=%d waiter=%d has bp=%d\n", __FUNCTION__, __LINE__, (long unsigned)(*the_target->read_pc)(get_thread_regcache (cs->ss->current_thread, 1)), cs->file_desc, waitee_has_bp, save_cs->file_desc, waiter_has_bp);
+		  }
+		if (waiter_has_bp)
+		  {
+		    /* fake the reply to the waiter client */
+		    if (debug_threads)
+		      debug_printf ("%s:%d normalize fd=%d\n", __FUNCTION__, __LINE__, cs->file_desc);
+		    normalize_packet (cs, 1);
+		    csidx->pending = none_pending;
+		    save_cs->pending = none_pending;
+		    if (!waitee_has_bp)
+		      cs->pending = pending_waitee;
+		  }
+		else if (debug_threads)
+		  {
+		    if (cs->ss->current_thread)
+		      debug_printf ("%s:%d fd=%d not normalized; no breakpoint at %#lx\n", __FUNCTION__, __LINE__, cs->file_desc, (long unsigned)(*the_target->read_pc)(get_thread_regcache (cs->ss->current_thread, 1)));
+		    else
+		      debug_printf ("%s:%d fd=%d not normalized; no breakpoint\n", __FUNCTION__, __LINE__, cs->file_desc);
+		  }
+		ch = save_ch;
+		cs = set_client_state (save_cs->file_desc);
+		if (!waitee_has_bp)
+		  {
+		    cs->pending = pending_cont_waiter;
+		    return 0;
+		  }
+	      }
+	    else if (cs->normalized_packet == 's' && csidx->normalized_packet == 's')
+	      {
+		char save_ch = ch;
+		client_state *save_cs = cs;
+		cs = set_client_state (csidx->file_desc);
+		/* fake the reply to the waiter client */
+		debug_printf ("%s:%d normalize fd=%d\n", __FUNCTION__, __LINE__, cs->file_desc);
+		normalize_packet (cs, 1);
+		csidx->pending = none_pending;
+		save_cs->pending = none_pending;
+		ch = save_ch;
+		cs = set_client_state (save_cs->file_desc);
+	      }
+	  }
+    }
+  return 1;
+}
+
+
+
 /* Post a stop reply to the stop reply queue.  */
 
 static void
@@ -622,7 +739,7 @@ start_inferior (char **argv)
       debug_flush ();
     }
 
-  add_client_state (new_argv[0]);
+  add_client_by_exe (cs, new_argv[0]);
 
 #ifdef SIGTTOU
   signal (SIGTTOU, SIG_DFL);
@@ -3062,7 +3179,7 @@ handle_v_attach (char *own_buf)
   if (debug_threads)
     debug_printf ("%s:%d %d %d\n", __FUNCTION__, __LINE__, cs->file_desc,pid);
 
-  if (attach_client_state (cs, pid))
+  if (add_client_by_pid (cs, pid))
     {
       strcpy (own_buf, "?");
       handle_status (own_buf);
@@ -3165,7 +3282,7 @@ handle_v_run (char *own_buf)
   freeargv (cs->program_argv);
   cs->program_argv = new_argv;
 
-  if (add_client_state (new_argv[0]))
+  if (add_client_by_exe (cs, new_argv[0]))
     {
       if (debug_threads)
 	debug_printf ("%s:%d returning 0 for vAttach;%d\n",__FUNCTION__, __LINE__, ptid_get_pid (cs->ss->last_ptid));
@@ -4197,8 +4314,9 @@ process_serial_event (gdb_client_data client_data)
     {
       gdb_fildes_t fdt;
       remote_close ();
+      fdt = get_first_client_fd ();
       /* Force an event loop break.  */
-      if (count_client_state (&fdt) == 0)
+      if (fdt == 0)
 	return -1;
       else
 	{
@@ -4231,42 +4349,8 @@ process_serial_event (gdb_client_data client_data)
 
   normalize_packet (cs, 0);
 
-  { /* Handle pending type */
-    client_state *csidx = NULL;
-
-    for (csidx = client_states.first; csidx != NULL; csidx = csidx->next)
-      {
-	/* another client is attached to the cs process */
-	if (csidx->file_desc != -1 && csidx != cs && cs->ss == csidx->ss)
-	  {
-	    if (debug_threads)
-	      debug_printf ("%s:%d csidx pending=%d packet=%d cs pending=%d packet=%d\n", __FUNCTION__, __LINE__, csidx->pending, csidx->normalized_packet, cs->pending, cs->normalized_packet);
-	    /* find this client's pending type */
-	    if (!csidx->pending)
-	      {
-		if (cs->normalized_packet == 'c')
-		  {
-		    cs->pending = pending_cont_waiter;
-		    csidx->pending = pending_waitee;
-
-		    if (debug_threads)
-		      debug_printf ("%s:%d pending check set %d %d\n", __FUNCTION__, __LINE__,csidx->file_desc,csidx->pending);
-		  }
-		else if (cs->normalized_packet == 's')
-		  {
-		    cs->pending = pending_step_waiter;
-		    csidx->pending = pending_waitee;
-		    if (debug_threads)


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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2015-08-25 14:13 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-25 14:13 [SCM] scox/dyninst: Add initial version of a multiple client gdbserver test scox

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).