Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Don Breazeal <donb@codesourcery.com>
To: <gdb-patches@sourceware.org>
Subject: [PATCH 1/3] Target remote mode fork and exec events
Date: Fri, 06 Nov 2015 23:57:00 -0000	[thread overview]
Message-ID: <1446854188-496-2-git-send-email-donb@codesourcery.com> (raw)
In-Reply-To: <1446854188-496-1-git-send-email-donb@codesourcery.com>

This patch implements support for fork and exec events with target remote
mode Linux targets.  For such targets with Linux kernels 2.5.46 and later,
this enables follow-fork-mode, detach-on-fork and fork and exec
catchpoints.  Note that follow-exec-mode is not supported, because target
remote mode does not support the 'run' command.

The changes required to implement this included:

 * Don't exit from gdbserver if there are still active inferiors.

 * Allow changing the active process in remote mode.

 * Enable fork and exec events in remote mode.

 * Print "Ending remote debugging" when detaching only if in remote
   mode and there is only one inferior left.

   (As I write this up I'm concluding that this is incorrect.  We
   don't care how many active inferiors there are, yes?  Perhaps we
   need a test that detaches when there are multiple inferiors. I've
   added that to my list.)

 * Combine remote_kill and extended_remote_kill into a single function
   that can handle the multiple inferior case for target remote.  Also,
   the same thing for remote_mourn and extended_remote_mourn.

 * Enable process-style ptids in target remote.

 * Remove restriction on multiprocess mode in target remote.

Thanks
--Don

gdb/gdbserver/
2015-11-06  Don Breazeal  <donb@sourceware.org>

	* server.c (process_serial_event): Don't exit from gdbserver
	in remote mode if there are still active inferiors.

gdb/
2015-11-06  Don Breazeal  <donb@sourceware.org>

	* remote.c (set_general_process): Remove restriction on target
	remote mode.
	(remote_query_supported): Likewise.
	(remote_detach_1): Change restriction to target remote mode to
	restriction to last inferior left.
	(remote_disconnect): Unpush the target directly instead of 
	calling remote_mourn.
	(remote_kill, extended_remote_kill): Combine functions into one,
	remote_kill, and enable extended functionality for target remote.
	(remote_mourn, extended_remote_mourn): Combine functions into
	one, remote_mourn, and enable extended functionality for target
	remote.
	(remote_pid_to_str): Enable "process" style ptid string for
	target remote.
	(remote_supports_multi_process): Remove restriction on target
	remote mode.

---
 gdb/gdbserver/server.c |   6 +-
 gdb/remote.c           | 166 ++++++++++++++++++++++++-------------------------
 2 files changed, 84 insertions(+), 88 deletions(-)

diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index fd2804b..0f57237 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -3865,9 +3865,11 @@ process_serial_event (void)
 	  discard_queued_stop_replies (pid_to_ptid (pid));
 	  write_ok (own_buf);
 
-	  if (extended_protocol)
+	  if (extended_protocol || get_first_inferior (&all_threads) != NULL)
 	    {
-	      /* Treat this like a normal program exit.  */
+	      /* There is still at least one inferior remaining, so
+		 don't terminate gdbserver and treat this like a
+		 normal program exit.  */
 	      last_status.kind = TARGET_WAITKIND_EXITED;
 	      last_status.value.integer = 0;
 	      last_ptid = pid_to_ptid (pid);
diff --git a/gdb/remote.c b/gdb/remote.c
index fed397a..60da26c 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -123,8 +123,6 @@ static void remote_mourn (struct target_ops *ops);
 
 static void extended_remote_restart (void);
 
-static void extended_remote_mourn (struct target_ops *);
-
 static void remote_send (char **buf, long *sizeof_buf_p);
 
 static int readchar (int timeout);
@@ -2084,7 +2082,7 @@ set_general_process (void)
   struct remote_state *rs = get_remote_state ();
 
   /* If the remote can't handle multiple processes, don't bother.  */
-  if (!rs->extended || !remote_multi_process_p (rs))
+  if (!remote_multi_process_p (rs))
     return;
 
   /* We only need to change the remote current thread if it's pointing
@@ -4472,18 +4470,15 @@ remote_query_supported (void)
 
       q = remote_query_supported_append (q, "qRelocInsn+");
 
-      if (rs->extended)
-	{
-	  if (packet_set_cmd_state (PACKET_fork_event_feature)
-	      != AUTO_BOOLEAN_FALSE)
-	    q = remote_query_supported_append (q, "fork-events+");
-	  if (packet_set_cmd_state (PACKET_vfork_event_feature)
-	      != AUTO_BOOLEAN_FALSE)
-	    q = remote_query_supported_append (q, "vfork-events+");
-	  if (packet_set_cmd_state (PACKET_exec_event_feature)
-	      != AUTO_BOOLEAN_FALSE)
-	    q = remote_query_supported_append (q, "exec-events+");
-	}
+      if (packet_set_cmd_state (PACKET_fork_event_feature)
+	  != AUTO_BOOLEAN_FALSE)
+	q = remote_query_supported_append (q, "fork-events+");
+      if (packet_set_cmd_state (PACKET_vfork_event_feature)
+	  != AUTO_BOOLEAN_FALSE)
+	q = remote_query_supported_append (q, "vfork-events+");
+      if (packet_set_cmd_state (PACKET_exec_event_feature)
+	  != AUTO_BOOLEAN_FALSE)
+	q = remote_query_supported_append (q, "exec-events+");
 
       if (packet_set_cmd_state (PACKET_vContSupported) != AUTO_BOOLEAN_FALSE)
 	q = remote_query_supported_append (q, "vContSupported+");
@@ -4827,7 +4822,8 @@ remote_detach_1 (const char *args, int from_tty)
   /* Tell the remote target to detach.  */
   remote_detach_pid (pid);
 
-  if (from_tty && !rs->extended)
+  /* Exit only if this is the only active inferior.  */
+  if (from_tty && !rs->extended && number_of_inferiors () == 1)
     puts_filtered (_("Ending remote debugging.\n"));
 
   /* Check to see if we are detaching a fork parent.  Note that if we
@@ -4923,10 +4919,11 @@ remote_disconnect (struct target_ops *target, const char *args, int from_tty)
   if (args)
     error (_("Argument given to \"disconnect\" when remotely debugging."));
 
-  /* Make sure we unpush even the extended remote targets; mourn
-     won't do it.  So call remote_mourn directly instead of
-     target_mourn_inferior.  */
-  remote_mourn (target);
+  /* Make sure we unpush even the extended remote targets.  Calling
+     target_mourn_inferior won't unpush, and remote_mourn won't
+     unpush if there is more than one inferior left.  */
+  unpush_target (target);
+  generic_mourn_inferior ();
 
   if (from_tty)
     puts_filtered ("Ending remote debugging.\n");
@@ -8562,42 +8559,6 @@ kill_new_fork_children (int pid, struct remote_state *rs)
 }
 
 \f
-static void
-remote_kill (struct target_ops *ops)
-{
-
-  /* Catch errors so the user can quit from gdb even when we
-     aren't on speaking terms with the remote system.  */
-  TRY
-    {
-      putpkt ("k");
-    }
-  CATCH (ex, RETURN_MASK_ERROR)
-    {
-      if (ex.error == TARGET_CLOSE_ERROR)
-	{
-	  /* If we got an (EOF) error that caused the target
-	     to go away, then we're done, that's what we wanted.
-	     "k" is susceptible to cause a premature EOF, given
-	     that the remote server isn't actually required to
-	     reply to "k", and it can happen that it doesn't
-	     even get to reply ACK to the "k".  */
-	  return;
-	}
-
-	/* Otherwise, something went wrong.  We didn't actually kill
-	   the target.  Just propagate the exception, and let the
-	   user or higher layers decide what to do.  */
-	throw_exception (ex);
-    }
-  END_CATCH
-
-  /* We've killed the remote end, we get to mourn it.  Since this is
-     target remote, single-process, mourning the inferior also
-     unpushes remote_ops.  */
-  target_mourn_inferior ();
-}
-
 static int
 remote_vkill (int pid, struct remote_state *rs)
 {
@@ -8624,19 +8585,58 @@ remote_vkill (int pid, struct remote_state *rs)
 }
 
 static void
-extended_remote_kill (struct target_ops *ops)
+remote_kill (struct target_ops *ops)
 {
   int res;
   int pid = ptid_get_pid (inferior_ptid);
   struct remote_state *rs = get_remote_state ();
 
+  /* If we are in 'target remote' mode and we are killing the only
+     inferior, then we will tell gdbserver to exit and unpush the
+     target.  */
+  if (!rs->extended && number_of_inferiors () <= 1)
+    {
+      /* Catch errors so the user can quit from gdb even when we
+	 aren't on speaking terms with the remote system.  */
+      TRY
+	{
+	  putpkt ("k");
+	}
+      CATCH (ex, RETURN_MASK_ERROR)
+	{
+	  if (ex.error == TARGET_CLOSE_ERROR)
+	    {
+	      /* If we got an (EOF) error that caused the target
+		 to go away, then we're done, that's what we wanted.
+		 "k" is susceptible to cause a premature EOF, given
+		 that the remote server isn't actually required to
+		 reply to "k", and it can happen that it doesn't
+		 even get to reply ACK to the "k".  */
+	      return;
+	    }
+
+	  /* Otherwise, something went wrong.  We didn't actually kill
+	     the target.  Just propagate the exception, and let the
+	     user or higher layers decide what to do.  */
+	  throw_exception (ex);
+	}
+      END_CATCH
+
+      /* We've killed the remote end, we get to mourn it.  Since this is
+	 target remote, single-process, mourning the inferior also
+	 unpushes remote_ops.  */
+      target_mourn_inferior ();
+
+      return;
+    }
+
   /* If we're stopped while forking and we haven't followed yet, kill the
      child task.  We need to do this before killing the parent task
      because if this is a vfork then the parent will be sleeping.  */
   kill_new_fork_children (pid, rs);
 
   res = remote_vkill (pid, rs);
-  if (res == -1 && !(rs->extended && remote_multi_process_p (rs)))
+  if (res == -1 && !(remote_multi_process_p (rs)))
     {
       /* Don't try 'k' on a multi-process aware stub -- it has no way
 	 to specify the pid.  */
@@ -8662,16 +8662,17 @@ extended_remote_kill (struct target_ops *ops)
 static void
 remote_mourn (struct target_ops *target)
 {
-  unpush_target (target);
+  struct remote_state *rs = get_remote_state ();
 
-  /* remote_close takes care of doing most of the clean up.  */
-  generic_mourn_inferior ();
-}
+  /* In 'target remote' mode with one inferior, we shut down gdbserver.  */
+  if (!rs->extended && number_of_inferiors () <= 1)
+    {
+      unpush_target (target);
 
-static void
-extended_remote_mourn (struct target_ops *target)
-{
-  struct remote_state *rs = get_remote_state ();
+      /* remote_close takes care of doing most of the clean up.  */
+      generic_mourn_inferior ();
+      return;
+    }
 
   /* In case we got here due to an error, but we're going to stay
      connected.  */
@@ -8702,8 +8703,9 @@ extended_remote_mourn (struct target_ops *target)
      current thread.  */
   record_currthread (rs, minus_one_ptid);
 
-  /* Unlike "target remote", we do not want to unpush the target; then
-     the next time the user says "run", we won't be connected.  */
+  /* Unlike 'target remote' with no more inferiors, we do not want to
+     unpush the target.  If we do then the next time the user says
+     "run", we won't be connected.  */
 
   /* Call common code to mark the inferior as not running.	*/
   generic_mourn_inferior ();
@@ -10224,7 +10226,7 @@ remote_pid_to_str (struct target_ops *ops, ptid_t ptid)
     {
       if (ptid_equal (magic_null_ptid, ptid))
 	xsnprintf (buf, sizeof buf, "Thread <main>");
-      else if (rs->extended && remote_multi_process_p (rs))
+      else if (remote_multi_process_p (rs))
 	if (ptid_get_lwp (ptid) == 0)
 	  return normal_pid_to_str (ptid);
 	else
@@ -11398,7 +11400,7 @@ remote_supports_multi_process (struct target_ops *self)
      processes, even though plain remote can use the multi-process
      thread id extensions, so that GDB knows the target process's
      PID.  */
-  return rs->extended && remote_multi_process_p (rs);
+  return remote_multi_process_p (rs);
 }
 
 static int
@@ -12828,6 +12830,14 @@ Specify the serial device it is connected to\n\
   remote_ops.to_btrace_conf = remote_btrace_conf;
   remote_ops.to_augmented_libraries_svr4_read =
     remote_augmented_libraries_svr4_read;
+  remote_ops.to_follow_fork = remote_follow_fork;
+  remote_ops.to_follow_exec = remote_follow_exec;
+  remote_ops.to_insert_fork_catchpoint = remote_insert_fork_catchpoint;
+  remote_ops.to_remove_fork_catchpoint = remote_remove_fork_catchpoint;
+  remote_ops.to_insert_vfork_catchpoint = remote_insert_vfork_catchpoint;
+  remote_ops.to_remove_vfork_catchpoint = remote_remove_vfork_catchpoint;
+  remote_ops.to_insert_exec_catchpoint = remote_insert_exec_catchpoint;
+  remote_ops.to_remove_exec_catchpoint = remote_remove_exec_catchpoint;
 }
 
 /* Set up the extended remote vector by making a copy of the standard
@@ -12846,27 +12856,11 @@ init_extended_remote_ops (void)
 Specify the serial device it is connected to (e.g. /dev/ttya).";
   extended_remote_ops.to_open = extended_remote_open;
   extended_remote_ops.to_create_inferior = extended_remote_create_inferior;
-  extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
   extended_remote_ops.to_detach = extended_remote_detach;
   extended_remote_ops.to_attach = extended_remote_attach;
   extended_remote_ops.to_post_attach = extended_remote_post_attach;
-  extended_remote_ops.to_kill = extended_remote_kill;
   extended_remote_ops.to_supports_disable_randomization
     = extended_remote_supports_disable_randomization;
-  extended_remote_ops.to_follow_fork = remote_follow_fork;
-  extended_remote_ops.to_follow_exec = remote_follow_exec;
-  extended_remote_ops.to_insert_fork_catchpoint
-    = remote_insert_fork_catchpoint;
-  extended_remote_ops.to_remove_fork_catchpoint
-    = remote_remove_fork_catchpoint;
-  extended_remote_ops.to_insert_vfork_catchpoint
-    = remote_insert_vfork_catchpoint;
-  extended_remote_ops.to_remove_vfork_catchpoint
-    = remote_remove_vfork_catchpoint;
-  extended_remote_ops.to_insert_exec_catchpoint
-    = remote_insert_exec_catchpoint;
-  extended_remote_ops.to_remove_exec_catchpoint
-    = remote_remove_exec_catchpoint;
 }
 
 static int
-- 
1.8.1.1


  parent reply	other threads:[~2015-11-06 23:57 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-06 23:56 [PATCH 0/3] Target remote mode fork and exec support Don Breazeal
2015-11-06 23:57 ` [PATCH 3/3] Target remote mode fork and exec docs Don Breazeal
2015-11-07  8:18   ` Eli Zaretskii
2015-11-12  1:00     ` Don Breazeal
2015-11-12 16:48       ` Eli Zaretskii
2015-11-13  1:13         ` Don Breazeal
2015-11-13  8:16           ` Eli Zaretskii
2015-11-12  1:00     ` Don Breazeal
2015-11-06 23:57 ` Don Breazeal [this message]
2015-11-20 13:04   ` [PATCH 1/3] Target remote mode fork and exec events Pedro Alves
2015-11-20 16:50     ` Don Breazeal
2015-12-07 22:14     ` [PATCH v2 0/3] Target remote mode fork and exec support Don Breazeal
2015-12-07 22:14       ` [PATCH v2 1/3] Target remote mode fork and exec tests Don Breazeal
2015-12-08 12:58         ` Pedro Alves
2015-12-14 19:29           ` [pushed] " Don Breazeal
2015-12-07 22:14       ` [PATCH v2 2/3] Target remote mode fork and exec events Don Breazeal
2015-12-08 12:55         ` Pedro Alves
2015-12-14 19:29           ` Don Breazeal
2015-12-15 10:52             ` Pedro Alves
2015-12-07 22:15       ` [PATCH v2 3/3] Target remote mode fork and exec docs Don Breazeal
2015-12-08 13:07         ` Pedro Alves
2015-12-14 19:30           ` [pushed] " Don Breazeal
2015-12-08 13:11       ` [PATCH v2 0/3] Target remote mode fork and exec support Pedro Alves
2015-11-06 23:57 ` [PATCH 2/3] Target remote mode fork and exec tests Don Breazeal

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=1446854188-496-2-git-send-email-donb@codesourcery.com \
    --to=donb@codesourcery.com \
    --cc=gdb-patches@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