Added send_thread_signal() function and properly handle errors caused

by the thread having already died when we send it a signal.
Use -1 instead of 0 as invalid Unix pid value.
This commit is contained in:
Alexandre Julliard 2003-02-25 04:17:22 +00:00
parent 4378d25bd2
commit 02a53c176e
6 changed files with 35 additions and 20 deletions

View File

@ -416,7 +416,7 @@ static int propagate_console_signal_cb(struct process *process, void *user)
while (thread) while (thread)
{ {
struct thread *next = thread->proc_next; struct thread *next = thread->proc_next;
kill( thread->unix_pid, csi->signal ); send_thread_signal( thread, csi->signal );
thread = next; thread = next;
} }
} }

View File

@ -720,11 +720,7 @@ DECL_HANDLER(debug_break)
struct thread *thread; struct thread *thread;
for (thread = process->thread_list; thread; thread = thread->proc_next) for (thread = process->thread_list; thread; thread = thread->proc_next)
{ {
if (thread->unix_pid) if (send_thread_signal( thread, SIGTRAP )) break;
{
kill( thread->unix_pid, SIGTRAP );
break;
}
} }
if (!thread) set_error( STATUS_ACCESS_DENIED ); if (!thread) set_error( STATUS_ACCESS_DENIED );
} }

View File

@ -969,7 +969,7 @@ DECL_HANDLER(get_startup_info)
/* initialize a new process */ /* initialize a new process */
DECL_HANDLER(init_process) DECL_HANDLER(init_process)
{ {
if (!current->unix_pid) if (current->unix_pid == -1)
{ {
fatal_protocol_error( current, "init_process: init_thread not called yet\n" ); fatal_protocol_error( current, "init_process: init_thread not called yet\n" );
return; return;

View File

@ -93,7 +93,7 @@ static int handle_child_status( struct thread *thread, int pid, int status )
if (thread && (WIFSIGNALED(status) || WIFEXITED(status))) if (thread && (WIFSIGNALED(status) || WIFEXITED(status)))
{ {
thread->attached = 0; thread->attached = 0;
thread->unix_pid = 0; thread->unix_pid = -1;
if (debug_level) if (debug_level)
{ {
if (WIFSIGNALED(status)) if (WIFSIGNALED(status))
@ -136,6 +136,23 @@ void wait4_thread( struct thread *thread, int signal )
} while (res && res != signal); } while (res && res != signal);
} }
/* send a Unix signal to a specific thread */
int send_thread_signal( struct thread *thread, int sig )
{
int ret = -1;
if (thread->unix_pid != -1)
{
ret = kill( thread->unix_pid, sig );
if (ret == -1 && errno == ESRCH) /* thread got killed */
{
thread->unix_pid = -1;
thread->attached = 0;
}
}
return (ret != -1);
}
/* attach to a Unix thread */ /* attach to a Unix thread */
static int attach_thread( struct thread *thread ) static int attach_thread( struct thread *thread )
{ {
@ -143,7 +160,7 @@ static int attach_thread( struct thread *thread )
if (!use_ptrace) return 0; if (!use_ptrace) return 0;
if (ptrace( PTRACE_ATTACH, thread->unix_pid, 0, 0 ) == -1) if (ptrace( PTRACE_ATTACH, thread->unix_pid, 0, 0 ) == -1)
{ {
if (errno == ESRCH) thread->unix_pid = 0; /* process got killed */ if (errno == ESRCH) thread->unix_pid = -1; /* thread got killed */
return 0; return 0;
} }
if (debug_level) fprintf( stderr, "%04x: *attached*\n", thread->id ); if (debug_level) fprintf( stderr, "%04x: *attached*\n", thread->id );
@ -155,12 +172,13 @@ static int attach_thread( struct thread *thread )
/* detach from a Unix thread and kill it */ /* detach from a Unix thread and kill it */
void detach_thread( struct thread *thread, int sig ) void detach_thread( struct thread *thread, int sig )
{ {
if (!thread->unix_pid) return; if (thread->unix_pid == -1) return;
if (thread->attached) if (thread->attached)
{ {
/* make sure it is stopped */ /* make sure it is stopped */
suspend_thread( thread, 0 ); suspend_thread( thread, 0 );
if (sig) kill( thread->unix_pid, sig ); if (sig) send_thread_signal( thread, sig );
if (thread->unix_pid == -1) return;
if (debug_level) fprintf( stderr, "%04x: *detached*\n", thread->id ); if (debug_level) fprintf( stderr, "%04x: *detached*\n", thread->id );
ptrace( PTRACE_DETACH, thread->unix_pid, (caddr_t)1, sig ); ptrace( PTRACE_DETACH, thread->unix_pid, (caddr_t)1, sig );
thread->suspend = 0; /* detach makes it continue */ thread->suspend = 0; /* detach makes it continue */
@ -168,7 +186,7 @@ void detach_thread( struct thread *thread, int sig )
} }
else else
{ {
if (sig) kill( thread->unix_pid, sig ); if (sig) send_thread_signal( thread, sig );
if (thread->suspend + thread->process->suspend) continue_thread( thread ); if (thread->suspend + thread->process->suspend) continue_thread( thread );
} }
} }
@ -177,21 +195,21 @@ void detach_thread( struct thread *thread, int sig )
void stop_thread( struct thread *thread ) void stop_thread( struct thread *thread )
{ {
/* can't stop a thread while initialisation is in progress */ /* can't stop a thread while initialisation is in progress */
if (!thread->unix_pid || !is_process_init_done(thread->process)) return; if (thread->unix_pid == -1 || !is_process_init_done(thread->process)) return;
/* first try to attach to it */ /* first try to attach to it */
if (!thread->attached) if (!thread->attached)
if (attach_thread( thread )) return; /* this will have stopped it */ if (attach_thread( thread )) return; /* this will have stopped it */
/* attached already, or attach failed -> send a signal */ /* attached already, or attach failed -> send a signal */
if (!thread->unix_pid) return; if (thread->unix_pid == -1) return;
kill( thread->unix_pid, SIGSTOP ); send_thread_signal( thread, SIGSTOP );
if (thread->attached) wait4_thread( thread, SIGSTOP ); if (thread->attached) wait4_thread( thread, SIGSTOP );
} }
/* make a thread continue (at the Unix level) */ /* make a thread continue (at the Unix level) */
void continue_thread( struct thread *thread ) void continue_thread( struct thread *thread )
{ {
if (!thread->unix_pid) return; if (thread->unix_pid == -1) return;
if (!thread->attached) kill( thread->unix_pid, SIGCONT ); if (!thread->attached) send_thread_signal( thread, SIGCONT );
else ptrace( get_thread_single_step(thread) ? PTRACE_SINGLESTEP : PTRACE_CONT, else ptrace( get_thread_single_step(thread) ? PTRACE_SINGLESTEP : PTRACE_CONT,
thread->unix_pid, (caddr_t)1, SIGSTOP ); thread->unix_pid, (caddr_t)1, SIGSTOP );
} }
@ -206,7 +224,7 @@ int suspend_for_ptrace( struct thread *thread )
return 1; return 1;
} }
/* can't stop a thread while initialisation is in progress */ /* can't stop a thread while initialisation is in progress */
if (!thread->unix_pid || !is_process_init_done(thread->process)) goto error; if (thread->unix_pid == -1 || !is_process_init_done(thread->process)) goto error;
thread->suspend++; thread->suspend++;
if (attach_thread( thread )) return 1; if (attach_thread( thread )) return 1;
thread->suspend--; thread->suspend--;

View File

@ -108,7 +108,7 @@ inline static void init_thread_structure( struct thread *thread )
{ {
int i; int i;
thread->unix_pid = 0; /* not known yet */ thread->unix_pid = -1; /* not known yet */
thread->context = NULL; thread->context = NULL;
thread->teb = NULL; thread->teb = NULL;
thread->mutex = NULL; thread->mutex = NULL;
@ -814,7 +814,7 @@ DECL_HANDLER(init_thread)
int reply_fd = thread_get_inflight_fd( current, req->reply_fd ); int reply_fd = thread_get_inflight_fd( current, req->reply_fd );
int wait_fd = thread_get_inflight_fd( current, req->wait_fd ); int wait_fd = thread_get_inflight_fd( current, req->wait_fd );
if (current->unix_pid) if (current->unix_pid != -1)
{ {
fatal_protocol_error( current, "init_thread: already running\n" ); fatal_protocol_error( current, "init_thread: already running\n" );
goto error; goto error;

View File

@ -135,6 +135,7 @@ extern int read_thread_int( struct thread *thread, const int *addr, int *data );
extern int write_thread_int( struct thread *thread, int *addr, int data, unsigned int mask ); extern int write_thread_int( struct thread *thread, int *addr, int data, unsigned int mask );
extern void *get_thread_ip( struct thread *thread ); extern void *get_thread_ip( struct thread *thread );
extern int get_thread_single_step( struct thread *thread ); extern int get_thread_single_step( struct thread *thread );
extern int send_thread_signal( struct thread *thread, int sig );
extern unsigned int global_error; /* global error code for when no thread is current */ extern unsigned int global_error; /* global error code for when no thread is current */