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>
+
+ * 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.
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)
linux_attach,
linux_kill,
linux_detach,
+ linux_join,
linux_thread_alive,
linux_resume,
linux_wait,
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)
{
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)
spu_attach,
spu_kill,
spu_detach,
+ spu_join,
spu_thread_alive,
spu_resume,
spu_wait,
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. */
#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);
}
/* Detach from all inferiors. */
-static void
+static int
win32_detach (void)
{
+ HANDLE h;
+
winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
#ifdef _WIN32_WCE
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. */
win32_attach,
win32_kill,
win32_detach,
+ win32_join,
win32_thread_alive,
win32_resume,
win32_wait,