* 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.
This commit is contained in:
Pedro Alves 2007-05-10 21:05:15 +00:00
parent 1d5315fee9
commit 444d61395b
6 changed files with 120 additions and 29 deletions

View 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> 2007-05-10 Pedro Alves <pedro_alves@portugalmail.pt>
* win32-low.c (win32-attach): Fix return value. * win32-low.c (win32-attach): Fix return value.

View File

@ -293,6 +293,19 @@ linux_detach (void)
for_each_inferior (&all_threads, linux_detach_one_process); 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. */ /* Return nonzero if the given thread is still alive. */
static int static int
linux_thread_alive (unsigned long tid) linux_thread_alive (unsigned long tid)
@ -1656,6 +1669,7 @@ static struct target_ops linux_target_ops = {
linux_attach, linux_attach,
linux_kill, linux_kill,
linux_detach, linux_detach,
linux_join,
linux_thread_alive, linux_thread_alive,
linux_resume, linux_resume,
linux_wait, linux_wait,

View File

@ -805,32 +805,27 @@ main (int argc, char *argv[])
case 'Q': case 'Q':
handle_general_set (own_buf); handle_general_set (own_buf);
break; break;
#ifndef USE_WIN32API
/* Skip "detach" support on mingw32, since we don't have
waitpid. */
case 'D': case 'D':
fprintf (stderr, "Detaching from inferior\n"); fprintf (stderr, "Detaching from inferior\n");
detach_inferior (); if (detach_inferior () != 0)
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)
{ {
int status, ret; write_enn (own_buf);
putpkt (own_buf);
do {
ret = waitpid (signal_pid, &status, 0);
if (WIFEXITED (status) || WIFSIGNALED (status))
break;
} while (ret != -1 || errno != ECHILD);
} }
else
{
write_ok (own_buf);
putpkt (own_buf);
remote_close ();
exit (0); /* If we are attached, then we can exit. Otherwise, we
#endif need to hang around doing nothing, until the child
is gone. */
if (!attached)
join_inferior ();
exit (0);
}
case '!': case '!':
if (attached == 0) if (attached == 0)
{ {

View File

@ -320,6 +320,18 @@ spu_detach (void)
ptrace (PTRACE_DETACH, current_tid, 0, 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. */ /* Return nonzero if the given thread is still alive. */
static int static int
spu_thread_alive (unsigned long tid) spu_thread_alive (unsigned long tid)
@ -567,6 +579,7 @@ static struct target_ops spu_target_ops = {
spu_attach, spu_attach,
spu_kill, spu_kill,
spu_detach, spu_detach,
spu_join,
spu_thread_alive, spu_thread_alive,
spu_resume, spu_resume,
spu_wait, spu_wait,

View File

@ -69,9 +69,14 @@ struct target_ops
void (*kill) (void); 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. */ /* 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) \ #define store_inferior_registers(regno) \
(*the_target->store_registers) (regno) (*the_target->store_registers) (regno)
#define join_inferior() \
(*the_target->join) ()
unsigned char mywait (char *statusp, int connected_wait); unsigned char mywait (char *statusp, int connected_wait);
int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len); int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len);

View File

@ -683,9 +683,11 @@ win32_kill (void)
} }
/* Detach from all inferiors. */ /* Detach from all inferiors. */
static void static int
win32_detach (void) win32_detach (void)
{ {
HANDLE h;
winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL; winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL; winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
@ -696,13 +698,53 @@ win32_detach (void)
DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop); DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit); DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
if (DebugSetProcessKillOnExit != NULL) if (DebugSetProcessKillOnExit == NULL
DebugSetProcessKillOnExit (FALSE); || DebugActiveProcessStop == NULL)
return -1;
if (DebugActiveProcessStop != NULL) /* We need a new handle, since DebugActiveProcessStop
DebugActiveProcessStop (current_process_id); closes all the ones that came through the events. */
else if ((h = OpenProcess (PROCESS_ALL_ACCESS,
win32_kill (); 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. */ /* 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_attach,
win32_kill, win32_kill,
win32_detach, win32_detach,
win32_join,
win32_thread_alive, win32_thread_alive,
win32_resume, win32_resume,
win32_wait, win32_wait,