* inferiors.c (started_inferior_callback): New function.
authorDoug Evans <dje@google.com>
Thu, 30 Apr 2009 22:21:06 +0000 (22:21 +0000)
committerDoug Evans <dje@google.com>
Thu, 30 Apr 2009 22:21:06 +0000 (22:21 +0000)
(attached_inferior_callback): New function.
(have_started_inferiors_p, have_attached_inferiors_p): New functions.
* server.c (print_started_pid, print_attached_pid): New functions.
(detach_or_kill_for_exit): New function.
(main): Call it instead of for_each_inferior (kill_inferior_callback).
* server.h (have_started_inferiors_p): Declare.
(have_attached_inferiors_p): Declare.

gdb/gdbserver/ChangeLog
gdb/gdbserver/inferiors.c
gdb/gdbserver/server.c
gdb/gdbserver/server.h

index a731bfff2e503fb0a83f1356f5b83f079ff88977..d710f61ed8e5547ac9c188f090a29436d474fdb8 100644 (file)
@@ -1,5 +1,14 @@
 2009-04-30  Doug Evans  <dje@google.com>
 
+       * inferiors.c (started_inferior_callback): New function.
+       (attached_inferior_callback): New function.
+       (have_started_inferiors_p, have_attached_inferiors_p): New functions.
+       * server.c (print_started_pid, print_attached_pid): New functions.
+       (detach_or_kill_for_exit): New function.
+       (main): Call it instead of for_each_inferior (kill_inferior_callback).
+       * server.h (have_started_inferiors_p): Declare.
+       (have_attached_inferiors_p): Declare.
+
        * inferiors.c (remove_process): Fix memory leak, free process.
        * linux-low.c (linux_remove_process): New function.
        (linux_kill): Call it instead of remove_process.
index 8d44d0160a2e717bcb38c5d60f0559c665ab70ab..8111e28f51874094d7d801529b00038ab33a5c6f 100644 (file)
@@ -127,6 +127,8 @@ add_inferior_to_list (struct inferior_list *list,
   list->tail = new_inferior;
 }
 
+/* Invoke ACTION for each inferior in LIST.  */
+
 void
 for_each_inferior (struct inferior_list *list,
                   void (*action) (struct inferior_list_entry *))
@@ -447,6 +449,46 @@ find_process_pid (int pid)
     find_inferior_id (&all_processes, pid_to_ptid (pid));
 }
 
+/* Return non-zero if INF, a struct process_info, was started by us,
+   i.e. not attached to.  */
+
+static int
+started_inferior_callback (struct inferior_list_entry *entry, void *args)
+{
+  struct process_info *process = (struct process_info *) entry;
+
+  return ! process->attached;
+}
+
+/* Return non-zero if there are any inferiors that we have created
+   (as opposed to attached-to).  */
+
+int
+have_started_inferiors_p (void)
+{
+  return (find_inferior (&all_processes, started_inferior_callback, NULL)
+         != NULL);
+}
+
+/* Return non-zero if INF, a struct process_info, was attached to.  */
+
+static int
+attached_inferior_callback (struct inferior_list_entry *entry, void *args)
+{
+  struct process_info *process = (struct process_info *) entry;
+
+  return process->attached;
+}
+
+/* Return non-zero if there are any inferiors that we have attached to.  */
+
+int
+have_attached_inferiors_p (void)
+{
+  return (find_inferior (&all_processes, attached_inferior_callback, NULL)
+         != NULL);
+}
+
 struct process_info *
 get_thread_process (struct thread_info *thread)
 {
index 998fd0ce9a3c04ef866bc01e9517ca7d82914233..24b163056a0c7c38216c82e4b917942d8c7a072e 100644 (file)
@@ -1808,6 +1808,11 @@ kill_inferior_callback (struct inferior_list_entry *entry)
   discard_queued_stop_replies (pid);
 }
 
+/* Callback for for_each_inferior to detach or kill the inferior,
+   depending on whether we attached to it or not.
+   We inform the user whether we're detaching or killing the process
+   as this is only called when gdbserver is about to exit.  */
+
 static void
 detach_or_kill_inferior_callback (struct inferior_list_entry *entry)
 {
@@ -1822,6 +1827,65 @@ detach_or_kill_inferior_callback (struct inferior_list_entry *entry)
   discard_queued_stop_replies (pid);
 }
 
+/* for_each_inferior callback for detach_or_kill_for_exit to print
+   the pids of started inferiors.  */
+
+static void
+print_started_pid (struct inferior_list_entry *entry)
+{
+  struct process_info *process = (struct process_info *) entry;
+
+  if (! process->attached)
+    {
+      int pid = ptid_get_pid (process->head.id);
+      fprintf (stderr, " %d", pid);
+    }
+}
+
+/* for_each_inferior callback for detach_or_kill_for_exit to print
+   the pids of attached inferiors.  */
+
+static void
+print_attached_pid (struct inferior_list_entry *entry)
+{
+  struct process_info *process = (struct process_info *) entry;
+
+  if (process->attached)
+    {
+      int pid = ptid_get_pid (process->head.id);
+      fprintf (stderr, " %d", pid);
+    }
+}
+
+/* Call this when exiting gdbserver with possible inferiors that need
+   to be killed or detached from.  */
+
+static void
+detach_or_kill_for_exit (void)
+{
+  /* First print a list of the inferiors we will be killing/detaching.
+     This is to assist the user, for example, in case the inferior unexpectedly
+     dies after we exit: did we screw up or did the inferior exit on its own?
+     Having this info will save some head-scratching.  */
+
+  if (have_started_inferiors_p ())
+    {
+      fprintf (stderr, "Killing process(es):");
+      for_each_inferior (&all_processes, print_started_pid);
+      fprintf (stderr, "\n");
+    }
+  if (have_attached_inferiors_p ())
+    {
+      fprintf (stderr, "Detaching process(es):");
+      for_each_inferior (&all_processes, print_attached_pid);
+      fprintf (stderr, "\n");
+    }
+
+  /* Now we can kill or detach the inferiors.  */
+
+  for_each_inferior (&all_processes, detach_or_kill_inferior_callback);
+}
+
 static void
 join_inferiors_callback (struct inferior_list_entry *entry)
 {
@@ -2015,9 +2079,7 @@ main (int argc, char *argv[])
 
   if (setjmp (toplevel))
     {
-      fprintf (stderr, "Killing all inferiors\n");
-      for_each_inferior (&all_processes,
-                        kill_inferior_callback);
+      detach_or_kill_for_exit ();
       exit (1);
     }
 
@@ -2062,8 +2124,7 @@ main (int argc, char *argv[])
 
       if (exit_requested)
        {
-         for_each_inferior (&all_processes,
-                            detach_or_kill_inferior_callback);
+         detach_or_kill_for_exit ();
          exit (0);
        }
       else
index 7a0b77054c21d98aa5297b93117e85c890c07356..5138f1a3c7e38b3b9a4fae801245ccb7b7feba00 100644 (file)
@@ -236,6 +236,8 @@ void add_thread (ptid_t ptid, void *target_data);
 struct process_info *add_process (int pid, int attached);
 void remove_process (struct process_info *process);
 struct process_info *find_process_pid (int pid);
+int have_started_inferiors_p (void);
+int have_attached_inferiors_p (void);
 
 struct thread_info *find_thread_pid (ptid_t ptid);