public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  scox/strace:  * server.c (set_client_state): Transfer initial commandline info.  (setup_multiplexing): syscall client cannot be waitee if it may not continue.  (notify_client):  Organize similarly to do_multiplexing.  Handle  syscall point similar to break point.  (do_multiplexing):  Likewise.  (handle_general_set):  Support strace -f and strace -e  * server.h (FOLLOW_CHILD):  New for strace -f  * linux-low.c (gdb_catch_this_syscall_p):  Support strace -f and strace -e  * gdb.server/multi-client.exp:  Add threaded test.
@ 2016-10-23 19:10 scox
  0 siblings, 0 replies; only message in thread
From: scox @ 2016-10-23 19:10 UTC (permalink / raw)
  To: archer-commits

The branch, scox/strace has been updated
       via  cf6f2ca1c40cfcbd5078edf12bf2ed887e8a7bfe (commit)
      from  29ed0969c6a127c58777f9c2a91f5dabc3dab909 (commit)

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

- Log -----------------------------------------------------------------
commit cf6f2ca1c40cfcbd5078edf12bf2ed887e8a7bfe
Author: Stan Cox <scox@redhat.com>
Date:   Sun Oct 23 15:08:53 2016 -0400

    	* server.c (set_client_state): Transfer initial commandline info.
    	(setup_multiplexing): syscall client cannot be waitee if it may not continue.
    	(notify_client):  Organize similarly to do_multiplexing.  Handle
    	syscall point similar to break point.
    	(do_multiplexing):  Likewise.
    	(handle_general_set):  Support strace -f and strace -e
    	* server.h (FOLLOW_CHILD):  New for strace -f
    	* linux-low.c (gdb_catch_this_syscall_p):  Support strace -f and strace -e
    	* gdb.server/multi-client.exp:  Add threaded test.

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

Summary of changes:
 gdb/gdbserver/ChangeLog                   |   15 ++
 gdb/gdbserver/linux-low.c                 |   32 ++-
 gdb/gdbserver/remote-utils.c              |   10 +-
 gdb/gdbserver/server.c                    |  379 ++++++++++++++---------------
 gdb/gdbserver/server.h                    |    3 +
 gdb/testsuite/ChangeLog                   |    6 +-
 gdb/testsuite/gdb.server/multi-client.exp |  186 ++++++++++++--
 7 files changed, 395 insertions(+), 236 deletions(-)

First 500 lines of diff:
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 6dd1329..1e32722 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,18 @@
+2016-10-23  Stan Cox  <scox@redhat.com>
+
+	* server.c (set_client_state): Transfer initial commandline info.
+	(setup_multiplexing): syscall client cannot be waitee if it may
+	not continue.
+	(notify_client):  Organize similarly to do_multiplexing.  Handle
+	syscall point similar to break point.
+	(do_multiplexing):  Likewise.
+	(handle_general_set):  Support strace -f and strace -e
+
+	* server.h (FOLLOW_CHILD):  New for strace -f
+
+	* linux-low.c (gdb_catch_this_syscall_p):  Support strace -f and
+	strace -e
+
 2016-09-14  Stan Cox  <scox@redhat.com>
 
 	* server.c:  Improve formatting and comments.
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index ec0481c..1adb781 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -74,9 +74,8 @@
 /* Some targets did not define these ptrace constants from the start,
    so gdbserver defines them locally here.  In the future, these may
    be removed after they are added to asm/ptrace.h.  */
-#if !(defined(PT_TEXT_ADDR) \
-      || defined(PT_DATA_ADDR) \
-      || defined(PT_TEXT_END_ADDR))
+/* This macro change is to circumvent an emacs semantic bug */
+#if !(defined(PT_TEXT_ADDR)       || defined(PT_DATA_ADDR)       || defined(PT_TEXT_END_ADDR))
 #if defined(__mcoldfire__)
 /* These are still undefined in 3.10 kernels.  */
 #define PT_TEXT_ADDR 49*4
@@ -3192,20 +3191,35 @@ gdb_catch_this_syscall_p (struct lwp_info *event_child)
   int sysno;
   struct thread_info *thread = get_lwp_thread (event_child);
   struct process_info *proc = get_thread_process (thread);
+  ptid thread_ptid = thread_to_gdb_id (thread);
+  ptid proc_ptid = ptid_of (proc);
 
   if (VEC_empty (int, proc->syscalls_to_catch))
     return 0;
 
-  if (VEC_index (int, proc->syscalls_to_catch, 0) == ANY_SYSCALL)
-    return 1;
-
   get_syscall_trapinfo (event_child, &sysno);
+
+  /* (FOLLOW,SYSCALL1,...,SYSCALLN) OR (FOLLOW,ANY) OR (ANY) */
+  if (VEC_index (int, proc->syscalls_to_catch, 0) != FOLLOW_CHILD
+      && (ptid_get_pid (thread_ptid) != ptid_get_pid (proc_ptid)
+	  || ptid_get_lwp (thread_ptid) != ptid_get_pid (thread_ptid)))
+      return 0;
+
   for (i = 0;
        VEC_iterate (int, proc->syscalls_to_catch, i, iter);
        i++)
-    if (iter == sysno)
-      return 1;
-
+    switch (iter)
+      {
+      case FOLLOW_CHILD:
+	break;
+      case ANY_SYSCALL:
+	return 1;
+	break;
+      default:
+	if (iter == sysno)
+	  return 1;
+      }
+  
   return 0;
 }
 
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index c9ae589..ed9ecbd 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -1479,6 +1479,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
   int len;
   struct sym_cache *sym;
   struct process_info *proc;
+  client_state *cs = get_client_state();
 
   proc = current_process ();
 
@@ -1503,7 +1504,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 (remote_desc, own_buffer);
+  len = getpkt (cs->file_desc, own_buffer);
   if (len < 0)
     return -1;
 
@@ -1541,7 +1542,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
 	}
       else
 	break;
-      len = getpkt (remote_desc, own_buffer);
+      len = getpkt (cs->file_desc, own_buffer);
       if (len < 0)
 	return -1;
     }
@@ -1590,6 +1591,7 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
 {
   int len;
   ULONGEST written = 0;
+  client_state *cs = get_client_state();
 
   /* Send the request.  */
   strcpy (own_buffer, "qRelocInsn:");
@@ -1599,7 +1601,7 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
     return -1;
 
   /* FIXME:  Eventually add buffer overflow checking (to getpkt?)  */
-  len = getpkt (remote_desc, own_buffer);
+  len = getpkt (cs->file_desc, own_buffer);
   if (len < 0)
     return -1;
 
@@ -1642,7 +1644,7 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
       free (mem_buffer);
       if (putpkt (own_buffer) < 0)
 	return -1;
-      len = getpkt (remote_desc, own_buffer);
+      len = getpkt (cs->file_desc, own_buffer);
       if (len < 0)
 	return -1;
     }
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index b03a4e6..cada601 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -121,10 +121,10 @@ get_client_state (void)
 client_state *
 set_client_state (gdb_fildes_t fd)
 {
-/* States:
- * fd = -1 add initial client state
- * fd =  F add client state for fd F
- */
+  /* States:
+   * fd = -1 add initial client state
+   * fd =  F add client state for fd F
+   */
 
   client_state *csidx, *cs;
 
@@ -176,10 +176,10 @@ set_client_state (gdb_fildes_t fd)
   cs->ss->last_ptid_ = null_ptid;
   cs->ss->last_status_.kind = TARGET_WAITKIND_IGNORE;
   cs->ss->current_thread_ = NULL;
-  cs->ss->all_processes_.head = NULL;
-  cs->ss->all_processes_.tail = NULL;
-  cs->ss->all_threads_.head = NULL;
-  cs->ss->all_threads_.tail = NULL;
+  client_states.first->ss->all_processes_.head = NULL;
+  client_states.first->ss->all_processes_.tail = NULL;
+  client_states.first->ss->all_threads_.head = NULL;
+  client_states.first->ss->all_threads_.tail = NULL;
   client_states.current_fd = fd;
   csidx->next = client_states.current_cs;
   return cs;
@@ -253,9 +253,9 @@ dump_client_state (const char *function, const char *comment)
 	debug_printf ("  *");
       else
 	debug_printf ("   ");
-      debug_printf ("%d %lu pc=%#lx #=%d %s %s %s %s %s\n",
+      debug_printf ("%d %s pc=%#lx #=%d %s %s %s %s %s\n",
 		    cs->file_desc, 
-		    (long unsigned)general_thread.pid,
+		    target_pid_to_str (general_thread),
 		    (long unsigned)pc,
 		    cs->ss->attach_count_,
 		    packet_types_str[cs->packet_type], 
@@ -424,17 +424,6 @@ get_packet_type (client_state *cs)
 }
 
 
-/* Is this client waiting on another client? */
-
-static int 
-is_waiter (client_state *cs)
-{
-  return ((cs->packet_type == vContc
-	   || cs->packet_type == vConts)
-	  && (cs->pending == pending_cont_waiter));
-}
-
-
 static int queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg);
 
 static void
@@ -446,9 +435,9 @@ vstop_notif_reply (struct notif_event *event, char *own_buf)
 }
 
 struct notif_server notif_stop =
-{
-  "vStopped", "Stop", NULL, vstop_notif_reply,
-};
+  {
+    "vStopped", "Stop", NULL, vstop_notif_reply,
+  };
 
 /* Belatedly reply to client CS, which is waiting on a packet reply. */
 
@@ -463,17 +452,17 @@ resolve_waiter (client_state *cs, client_state *waitee_cs)
   set_client_state (cs->file_desc);
   if (debug_threads)
     {
-       debug_printf ("%s:%d fd=%d %s %s", __FUNCTION__, __LINE__, 
-		     cs->file_desc, packet_types_str[this_packet_type],
-		     pending_types_str[cs->pending]);
-       if (waitee_cs)
+      debug_printf ("%s:%d fd=%d %s %s", __FUNCTION__, __LINE__, 
+		    cs->file_desc, packet_types_str[this_packet_type],
+		    pending_types_str[cs->pending]);
+      if (waitee_cs)
  	debug_printf (" fd=%d %s %s", waitee_cs->file_desc,
 		      packet_types_str[waitee_cs->packet_type],
 		      pending_types_str[waitee_cs->pending]);
-       debug_printf ("\n");
-     }
+      debug_printf ("\n");
+    }
   switch (this_packet_type)
-  {
+    {
     case vContc:
       {
 	strcpy (own_buffer, "?");
@@ -503,57 +492,57 @@ resolve_waiter (client_state *cs, client_state *waitee_cs)
 	  }
 	break;
       }
-  case vConts:
-    {
-      if (non_stop)
-	{
-	  if (last_status.kind != TARGET_WAITKIND_EXITED)
-	    cs->nonstop_pending = pending_notifier;
-	}
-      else if (last_status.kind != TARGET_WAITKIND_EXITED)
-	{
-	  putpkt (waitee_cs->own_buffer_);
-	}
-      else if (last_status.kind == TARGET_WAITKIND_EXITED)
-	{
-	  putpkt (waitee_cs->own_buffer_);
-	}
-      break;
-    }
-  case vContt:
-    {
-      if (last_status.kind != TARGET_WAITKIND_EXITED
-	  && last_status.kind != TARGET_WAITKIND_STOPPED)
-	{
-	  char *notif_buf, *out_buf;
-	  notif_buf = (char*) alloca (PBUFSIZ + 1);
-	  write_ok (notif_buf);
-	  putpkt (notif_buf);
-
-	  find_inferior (&all_threads, queue_stop_reply_callback, NULL);
-	  notif_write_event (&notif_stop, notif_buf);
-	  out_buf = (char*) alloca (strlen (notif_buf) + 8);
-	  /* TODO Use Defined notif constant */
-	  xsnprintf (out_buf, PBUFSIZ, "%s:", notif_stop.notif_name);
-	  strcat (out_buf, notif_buf);
-	  if (debug_threads)
-	    debug_printf ("%s:%d Notifying fd=%d\n", __FUNCTION__, __LINE__,
-			  cs->file_desc);
-	  putpkt_notif (out_buf);
-	  if (debug_threads)
-	    debug_printf ("%s:%d %s\n", __FUNCTION__, __LINE__, out_buf);
-	}
-      break;
-    }
-  case vRun:
-    {
-      strcpy (own_buffer, "OK");
-      putpkt (own_buffer);
+    case vConts:
+      {
+	if (non_stop)
+	  {
+	    if (last_status.kind != TARGET_WAITKIND_EXITED)
+	      cs->nonstop_pending = pending_notifier;
+	  }
+	else if (last_status.kind != TARGET_WAITKIND_EXITED)
+	  {
+	    putpkt (waitee_cs->own_buffer_);
+	  }
+	else if (last_status.kind == TARGET_WAITKIND_EXITED)
+	  {
+	    putpkt (waitee_cs->own_buffer_);
+	  }
+	break;
+      }
+    case vContt:
+      {
+	if (last_status.kind != TARGET_WAITKIND_EXITED
+	    && last_status.kind != TARGET_WAITKIND_STOPPED)
+	  {
+	    char *notif_buf, *out_buf;
+	    notif_buf = (char*) alloca (PBUFSIZ + 1);
+	    write_ok (notif_buf);
+	    putpkt (notif_buf);
+
+	    find_inferior (&all_threads, queue_stop_reply_callback, NULL);
+	    notif_write_event (&notif_stop, notif_buf);
+	    out_buf = (char*) alloca (strlen (notif_buf) + 8);
+	    /* TODO Use Defined notif constant */
+	    xsnprintf (out_buf, PBUFSIZ, "%s:", notif_stop.notif_name);
+	    strcat (out_buf, notif_buf);
+	    if (debug_threads)
+	      debug_printf ("%s:%d Notifying fd=%d\n", __FUNCTION__, __LINE__,
+			    cs->file_desc);
+	    putpkt_notif (out_buf);
+	    if (debug_threads)
+	      debug_printf ("%s:%d %s\n", __FUNCTION__, __LINE__, out_buf);
+	  }
+	break;
+      }
+    case vRun:
+      {
+	strcpy (own_buffer, "OK");
+	putpkt (own_buffer);
+	break;
+      }
+    default:
       break;
-    }
-  default:
-    break;
-  };
+    };
 
   set_client_state (save_client_state->file_desc);
 }
@@ -586,22 +575,22 @@ static int
 setup_multiplexing (client_state *current_cs)
 {
   /***
-  If we have two independent clients 4 and 7 and 4 is the current
-  client with a vConts packet then we change both client's state
-  BEFORE
-  packet_type last_packet_type pending last_status_.kind
-  4 vConts    vConts	   not-waiting stopped
-  7 other     vAttach	   not-waiting stopped
-  AFTER
-  4 vConts    vConts	   step-waiter stopped
-  7 other     vAttach	   waitee      stopped
-
-  If we have two dependent clients 4 and 7 and 4 is the current client with a
-  vContc packet then we change nothing here.  process_serial_event will handle
-  the vContc then do_multiplexing will decide to either continue with client 4
-  or wakeup and continue with client 7.
-  4 vContc vConts waitee stopped
-  7 vContc vContc waiter stopped
+      If we have two independent clients 4 and 7 and 4 is the current
+      client with a vConts packet then we change both client's state
+      BEFORE
+      packet_type last_packet_type pending last_status_.kind
+      4 vConts    vConts	   not-waiting stopped
+      7 other     vAttach	   not-waiting stopped
+      AFTER
+      4 vConts    vConts	   step-waiter stopped
+      7 other     vAttach	   waitee      stopped
+
+      If we have two dependent clients 4 and 7 and 4 is the current client with a
+      vContc packet then we change nothing here.  process_serial_event will handle
+      the vContc then do_multiplexing will decide to either continue with client 4
+      or wakeup and continue with client 7.
+      4 vContc vConts waitee stopped
+      7 vContc vContc waiter stopped
   ***/
 
   client_state *same_pid_cs = NULL;
@@ -638,7 +627,7 @@ setup_multiplexing (client_state *current_cs)
 	case /* same_pid_cs->pending */ pending_cont_waiter:
 	  switch (current_cs->packet_type)
 	    {
-	    /* Current client is continuing and found another waiter client */
+	      /* Current client is continuing and found another waiter client */
 	    case /* current_cs->packet_type */ vContc:
 	      {
 		int have_waitee;
@@ -654,10 +643,13 @@ setup_multiplexing (client_state *current_cs)
 	case /* same_pid_cs->pending */ pending_waitee:
 	  switch (current_cs->packet_type)
 	    {
-	    /* Current client is continuing and found another waitee client */
+	      /* Current client is continuing and found another waitee client */
 	    case /* current_cs->packet_type */ vContc:
 	      {
-		current_cs->pending = pending_cont_waiter;
+		/* Don't make a syscall client a waitee as a waiter cannot 
+		   depend on receiving a reply from it */
+		if (! same_pid_cs->catch_syscalls)
+		  current_cs->pending = pending_cont_waiter;
 	      }
 	      break;
 	    }
@@ -695,19 +687,21 @@ setup_multiplexing (client_state *current_cs)
 }
 
 
-/* Send a notification to a pending client.
-   Called via the handle_target_event notification mechanism. */
+/* Send a notification to a pending client.  Called via the
+   handle_target_event notification mechanism.  This is a non-stop
+   variation of do_multiplexing */
 
 int
 notify_clients (char *buffer, int have_first_notify)
 {
   client_state *same_pid_cs = NULL;
   int save_client_fd = client_states.current_fd;
-  client_state *save_client_cs = client_states.current_cs;
+  client_state *current_cs = client_states.current_cs;
   char *okay_buf = (char*) alloca (4);
   int have_syscall = 0;
+  int make_waitee_a_waiter = 0;
 
-  dump_client_state (__FUNCTION__, "");
+  dump_client_state (__FUNCTION__, have_first_notify ? "first" : "not first");
 
   write_ok (okay_buf);
 
@@ -715,69 +709,86 @@ notify_clients (char *buffer, int have_first_notify)
        same_pid_cs != NULL;
        same_pid_cs = same_pid_cs->next)
     {
+      client_state *waiter_cs = NULL;
+
       /* Is this a client attached to the same process? */
       if (! attached_to_same_proc (client_states.current_cs, same_pid_cs))
 	continue;
 
       switch (last_status.kind)
-      {
+	{
+	case TARGET_WAITKIND_EXITED:
+	  waiter_cs = set_client_state (same_pid_cs->file_desc);
+	  make_waitee_a_waiter = 1;
+	  same_pid_cs->nonstop_pending = pending_notifier;
+	  break;
 	case TARGET_WAITKIND_SYSCALL_ENTRY:
 	case TARGET_WAITKIND_SYSCALL_RETURN:
+	  /* current client continued and got a syscall 
+	     which another client was waiting for */
 	  have_syscall = 1;
-	  break;
-	case TARGET_WAITKIND_EXITED:
-	  set_client_state (same_pid_cs->file_desc);
-	  putpkt (okay_buf);
-	  putpkt_notif (buffer);
-	  set_client_state (save_client_fd);
-	  return 1;
-        case TARGET_WAITKIND_STOPPED:
-	  /* pending client will also want a notify */
-	  if (save_client_cs->packet_type == vStopped)
+	  if (same_pid_cs->catch_syscalls)
 	    {
+	      waiter_cs = set_client_state (same_pid_cs->file_desc);
+	      make_waitee_a_waiter = 1;
 	      same_pid_cs->nonstop_pending = pending_notifier;
 	    }
-
+	  break;
+        case TARGET_WAITKIND_STOPPED:
 	default:
-	  /* syscall clients only need to see a syscall packet */
-	  if (save_client_cs->catch_syscalls)
+	  /* we want only syscalls but got something else */
+	  if (current_cs->catch_syscalls)
 	    {
-	      set_client_state (same_pid_cs->file_desc);
-	      return 1;
+	      waiter_cs = set_client_state (same_pid_cs->file_desc);
+	      make_waitee_a_waiter = 1;
+	      same_pid_cs->nonstop_pending = pending_notifier;
 	    }
+	  break;
       }
 
+      debug_printf ("%s:%d after switch first=%d have_syscall=%d notifier=%d/%d\n", __FUNCTION__, __LINE__, have_first_notify, have_syscall, current_cs->nonstop_pending, same_pid_cs->nonstop_pending);
       /* syscall continue was erroneously caught by by a non syscall client */
-      if (save_client_cs->packet_type == other_packet
-	  && same_pid_cs->catch_syscalls)
-	return 0;
+      dump_client_state ("","");


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


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

only message in thread, other threads:[~2016-10-23 19:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-23 19:10 [SCM] scox/strace: * server.c (set_client_state): Transfer initial commandline info. (setup_multiplexing): syscall client cannot be waitee if it may not continue. (notify_client): Organize similarly to do_multiplexing. Handle syscall point similar to break point. (do_multiplexing): Likewise. (handle_general_set): Support strace -f and strace -e * server.h (FOLLOW_CHILD): New for strace -f * linux-low.c (gdb_catch_this_syscall_p): Support strace -f and strace -e * gdb.server/multi-client.exp: Add threaded 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).