* target.h (target_ops): Change return type of detach to int.
authorPedro Alves <palves@redhat.com>
Thu, 10 May 2007 21:05:15 +0000 (21:05 +0000)
committerPedro Alves <palves@redhat.com>
Thu, 10 May 2007 21:05:15 +0000 (21:05 +0000)
Add join.
(join_inferior): New.
* server.c (main): Don't skip detach support on mingw32.
If the inferior doesn't support detaching return error.
Call join_inferior instead of using waitpid.
* linux-low.c (linux_join): New.
(linux_target_op): Add linux_join.
* spu-low.c (spu_join): New.
(spu_target_ops): Add spu_join.
* win32-low.c (win32_detach): Adapt to new interface.
Reopen current_process_handle before detaching.  Issue a child
resume before detaching.
(win32_join): New.
(win32_target_op): Add win32_join.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c
gdb/gdbserver/server.c
gdb/gdbserver/spu-low.c
gdb/gdbserver/target.h
gdb/gdbserver/win32-low.c

index f9499544a667d87a272dd53425a5ce399096a835..8cf4496924d7b243fdddfc0dfad284468ba1a801 100644 (file)
@@ -1,3 +1,21 @@
+2007-05-10  Pedro Alves  <pedro_alves@portugalmail.pt>
+
+       * target.h (target_ops): Change return type of detach to int.
+       Add join.
+       (join_inferior): New.
+       * server.c (main): Don't skip detach support on mingw32.
+       If the inferior doesn't support detaching return error.
+       Call join_inferior instead of using waitpid.
+       * linux-low.c (linux_join): New.
+       (linux_target_op): Add linux_join.
+       * spu-low.c (spu_join): New.
+       (spu_target_ops): Add spu_join.
+       * win32-low.c (win32_detach): Adapt to new interface.
+       Reopen current_process_handle before detaching.  Issue a child
+       resume before detaching.
+       (win32_join): New.
+       (win32_target_op): Add win32_join.
+
 2007-05-10  Pedro Alves  <pedro_alves@portugalmail.pt>
 
        * win32-low.c (win32-attach): Fix return value.
index ff4f81e60c20548454d92fa57e3d9d1fb605f726..2ea54c3543625555ad6670c63cafa6a949c84fc6 100644 (file)
@@ -293,6 +293,19 @@ linux_detach (void)
   for_each_inferior (&all_threads, linux_detach_one_process);
 }
 
+static void
+linux_join (void)
+{
+  extern unsigned long signal_pid;
+  int status, ret;
+
+  do {
+    ret = waitpid (signal_pid, &status, 0);
+    if (WIFEXITED (status) || WIFSIGNALED (status))
+      break;
+  } while (ret != -1 || errno != ECHILD);
+}
+
 /* Return nonzero if the given thread is still alive.  */
 static int
 linux_thread_alive (unsigned long tid)
@@ -1656,6 +1669,7 @@ static struct target_ops linux_target_ops = {
   linux_attach,
   linux_kill,
   linux_detach,
+  linux_join,
   linux_thread_alive,
   linux_resume,
   linux_wait,
index 61a08a175d6eb7c9e0e1a3ba20b9b87f9dad540c..ca18a1d6c448abb94613319a4a73a7803db679b8 100644 (file)
@@ -805,32 +805,27 @@ main (int argc, char *argv[])
            case 'Q':
              handle_general_set (own_buf);
              break;
-#ifndef USE_WIN32API
-           /* Skip "detach" support on mingw32, since we don't have
-              waitpid.  */
            case 'D':
              fprintf (stderr, "Detaching from inferior\n");
-             detach_inferior ();
-             write_ok (own_buf);
-             putpkt (own_buf);
-             remote_close ();
-
-             /* If we are attached, then we can exit.  Otherwise, we need to
-                hang around doing nothing, until the child is gone.  */
-             if (!attached)
+             if (detach_inferior () != 0)
                {
-                 int status, ret;
-
-                 do {
-                   ret = waitpid (signal_pid, &status, 0);
-                   if (WIFEXITED (status) || WIFSIGNALED (status))
-                     break;
-                 } while (ret != -1 || errno != ECHILD);
+                 write_enn (own_buf);
+                 putpkt (own_buf);
                }
+             else
+               {
+                 write_ok (own_buf);
+                 putpkt (own_buf);
+                 remote_close ();
 
-             exit (0);
-#endif
+                 /* If we are attached, then we can exit.  Otherwise, we
+                    need to hang around doing nothing, until the child
+                    is gone.  */
+                 if (!attached)
+                   join_inferior ();
 
+                 exit (0);
+               }
            case '!':
              if (attached == 0)
                {
index 0d1c81ad92c2de38b19ac2ce4d41f0ca4e5b4dd1..5dbc8116660ff4a63083ce974b08a4e5e73089a7 100644 (file)
@@ -320,6 +320,18 @@ spu_detach (void)
   ptrace (PTRACE_DETACH, current_tid, 0, 0);
 }
 
+static void
+spu_join (void)
+{
+  int status, ret;
+
+  do {
+    ret = waitpid (current_tid, &status, 0);
+    if (WIFEXITED (status) || WIFSIGNALED (status))
+      break;
+  } while (ret != -1 || errno != ECHILD);
+}
+
 /* Return nonzero if the given thread is still alive.  */
 static int
 spu_thread_alive (unsigned long tid)
@@ -567,6 +579,7 @@ static struct target_ops spu_target_ops = {
   spu_attach,
   spu_kill,
   spu_detach,
+  spu_join,
   spu_thread_alive,
   spu_resume,
   spu_wait,
index 36cc69a975fd486ec90c433283d193a0c3af9d03..66511c90b5838670a79be8045728dec98a3d9149 100644 (file)
@@ -69,9 +69,14 @@ struct target_ops
 
   void (*kill) (void);
 
-  /* Detach from all inferiors.  */
+  /* Detach from all inferiors.
+     Return -1 on failure, and 0 on success.  */
 
-  void (*detach) (void);
+  int (*detach) (void);
+
+  /* Wait for inferiors to end.  */
+
+  void (*join) (void);
 
   /* Return 1 iff the thread with process ID PID is alive.  */
 
@@ -207,6 +212,9 @@ void set_target_ops (struct target_ops *);
 #define store_inferior_registers(regno) \
   (*the_target->store_registers) (regno)
 
+#define join_inferior() \
+  (*the_target->join) ()
+
 unsigned char mywait (char *statusp, int connected_wait);
 
 int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len);
index 265c91691fb85aac53e12770ff59d7d0024be29f..e980db4c85e1f4ee3defd0ec381f717c098fcea4 100644 (file)
@@ -683,9 +683,11 @@ win32_kill (void)
 }
 
 /* Detach from all inferiors.  */
-static void
+static int
 win32_detach (void)
 {
+  HANDLE h;
+
   winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
   winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
 #ifdef _WIN32_WCE
@@ -696,13 +698,53 @@ win32_detach (void)
   DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
   DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
 
-  if (DebugSetProcessKillOnExit != NULL)
-    DebugSetProcessKillOnExit (FALSE);
+  if (DebugSetProcessKillOnExit == NULL
+      || DebugActiveProcessStop == NULL)
+    return -1;
 
-  if (DebugActiveProcessStop != NULL)
-    DebugActiveProcessStop (current_process_id);
-  else
-    win32_kill ();
+  /* We need a new handle, since DebugActiveProcessStop
+     closes all the ones that came through the events.  */
+  if ((h = OpenProcess (PROCESS_ALL_ACCESS,
+                       FALSE,
+                       current_process_id)) == NULL)
+    {
+      /* The process died.  */
+      return -1;
+    }
+
+  {
+    struct thread_resume resume;
+    resume.thread = -1;
+    resume.step = 0;
+    resume.sig = 0;
+    resume.leave_stopped = 0;
+    win32_resume (&resume);
+  }
+
+  if (!DebugActiveProcessStop (current_process_id))
+    {
+      CloseHandle (h);
+      return -1;
+    }
+  DebugSetProcessKillOnExit (FALSE);
+
+  current_process_handle = h;
+  return 0;
+}
+
+/* Wait for inferiors to end.  */
+static void
+win32_join (void)
+{
+  if (current_process_id == 0
+      || current_process_handle == NULL)
+    return;
+
+  WaitForSingleObject (current_process_handle, INFINITE);
+  CloseHandle (current_process_handle);
+
+  current_process_handle = NULL;
+  current_process_id = 0;
 }
 
 /* Return 1 iff the thread with thread ID TID is alive.  */
@@ -1160,6 +1202,7 @@ static struct target_ops win32_target_ops = {
   win32_attach,
   win32_kill,
   win32_detach,
+  win32_join,
   win32_thread_alive,
   win32_resume,
   win32_wait,