* 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:
parent
1d5315fee9
commit
444d61395b
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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_enn (own_buf);
|
||||||
|
putpkt (own_buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
write_ok (own_buf);
|
write_ok (own_buf);
|
||||||
putpkt (own_buf);
|
putpkt (own_buf);
|
||||||
remote_close ();
|
remote_close ();
|
||||||
|
|
||||||
/* If we are attached, then we can exit. Otherwise, we need to
|
/* If we are attached, then we can exit. Otherwise, we
|
||||||
hang around doing nothing, until the child is gone. */
|
need to hang around doing nothing, until the child
|
||||||
|
is gone. */
|
||||||
if (!attached)
|
if (!attached)
|
||||||
{
|
join_inferior ();
|
||||||
int status, ret;
|
|
||||||
|
|
||||||
do {
|
|
||||||
ret = waitpid (signal_pid, &status, 0);
|
|
||||||
if (WIFEXITED (status) || WIFSIGNALED (status))
|
|
||||||
break;
|
|
||||||
} while (ret != -1 || errno != ECHILD);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit (0);
|
exit (0);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
case '!':
|
case '!':
|
||||||
if (attached == 0)
|
if (attached == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|| DebugActiveProcessStop == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* 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);
|
DebugSetProcessKillOnExit (FALSE);
|
||||||
|
|
||||||
if (DebugActiveProcessStop != NULL)
|
current_process_handle = h;
|
||||||
DebugActiveProcessStop (current_process_id);
|
return 0;
|
||||||
else
|
}
|
||||||
win32_kill ();
|
|
||||||
|
/* 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,
|
||||||
|
|
Loading…
Reference in New Issue