Make a distinction between the thread Unix pid and the process wide

pid for platforms that use both.
This commit is contained in:
Alexandre Julliard 2003-03-22 21:00:09 +00:00
parent 5cdfa593c0
commit a8497bd037
11 changed files with 70 additions and 12 deletions

View File

@ -301,6 +301,7 @@ struct init_thread_request
{
struct request_header __header;
int unix_pid;
int unix_tid;
void* teb;
void* entry;
int reply_fd;
@ -3556,6 +3557,6 @@ union generic_reply
struct get_next_hook_reply get_next_hook_reply;
};
#define SERVER_PROTOCOL_VERSION 101
#define SERVER_PROTOCOL_VERSION 102
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -695,6 +695,7 @@ void CLIENT_InitThread(void)
SERVER_START_REQ( init_thread )
{
req->unix_pid = getpid();
req->unix_tid = -1;
req->teb = teb;
req->entry = teb->entry_point;
req->reply_fd = reply_pipe[1];

View File

@ -178,7 +178,7 @@ int SYSDEPS_SpawnThread( TEB *teb )
{
#ifdef HAVE_CLONE
if (clone( (int (*)(void *))SYSDEPS_StartThread, teb->stack_top,
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, teb ) < 0)
CLONE_VM | CLONE_FS | CLONE_FILES, teb ) < 0)
return -1;
return 0;
#elif defined(HAVE_RFORK)

View File

@ -101,7 +101,9 @@ struct kernel_user_regs_struct
/* retrieve a debug register */
static inline int get_debug_reg( int pid, int num, DWORD *data )
{
int res = ptrace( PTRACE_PEEKUSER, pid, DR_OFFSET(num), 0 );
int res;
errno = 0;
res = ptrace( PTRACE_PEEKUSER, pid, DR_OFFSET(num), 0 );
if ((res == -1) && errno)
{
file_set_error();
@ -548,6 +550,26 @@ int get_thread_single_step( struct thread *thread )
return (context.EFlags & 0x100) != 0;
}
/* send a signal to a specific thread */
int tkill( int pid, int sig )
{
#ifdef __linux__
int ret;
__asm__( "pushl %%ebx\n\t"
"movl %2,%%ebx\n\t"
"int $0x80\n\t"
"popl %%ebx\n\t"
: "=a" (ret)
: "0" (238) /*SYS_tkill*/, "r" (pid), "c" (sig) );
if (ret > 0) return ret;
errno = -ret;
return -1;
#else
errno = ENOSYS;
return -1;
#endif
}
/* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context)
{

View File

@ -269,6 +269,14 @@ int get_thread_single_step( struct thread *thread )
return (context.Msr & MSR_SE) != 0;
}
/* send a signal to a specific thread */
int tkill( int pid, int sig )
{
/* FIXME: should do something here */
errno = ENOSYS;
return -1;
}
/* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context)
{

View File

@ -175,6 +175,14 @@ int get_thread_single_step( struct thread *thread )
return 0; /* FIXME */
}
/* send a signal to a specific thread */
int tkill( int pid, int sig )
{
/* FIXME: should do something here */
errno = ENOSYS;
return -1;
}
/* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context)
{

View File

@ -279,6 +279,7 @@ typedef struct
/* Initialize a thread; called from the child after fork()/clone() */
@REQ(init_thread)
int unix_pid; /* Unix pid of new thread */
int unix_tid; /* Unix tid of new thread */
void* teb; /* TEB of new thread (in thread address space) */
void* entry; /* thread entry point (in thread address space) */
int reply_fd; /* fd for reply pipe */

View File

@ -66,6 +66,10 @@
inline static int ptrace(int req, ...) { errno = EPERM; return -1; /*FAIL*/ }
#endif /* HAVE_SYS_PTRACE_H */
#ifndef __WALL
#define __WALL 0
#endif
static const int use_ptrace = 1; /* set to 0 to disable ptrace */
/* handle a status returned by wait4 */
@ -90,6 +94,7 @@ static int handle_child_status( struct thread *thread, int pid, int status, int
{
thread->attached = 0;
thread->unix_pid = -1;
thread->unix_tid = -1;
if (debug_level)
{
if (WIFSIGNALED(status))
@ -110,7 +115,7 @@ void sigchld_handler()
for (;;)
{
if (!(pid = wait4( -1, &status, WUNTRACED | WNOHANG, NULL ))) break;
if (!(pid = wait4( -1, &status, WUNTRACED | WNOHANG | __WALL, NULL ))) break;
if (pid != -1) handle_child_status( get_thread_from_pid(pid), pid, status, -1 );
else break;
}
@ -123,11 +128,12 @@ static void wait4_thread( struct thread *thread, int signal )
do
{
if ((res = wait4( get_ptrace_pid(thread), &status, WUNTRACED, NULL )) == -1)
if ((res = wait4( get_ptrace_pid(thread), &status, WUNTRACED | __WALL, NULL )) == -1)
{
if (errno == ECHILD) /* must have died */
{
thread->unix_pid = -1;
thread->unix_tid = -1;
thread->attached = 0;
}
else perror( "wait4" );
@ -140,6 +146,7 @@ static void wait4_thread( struct thread *thread, int signal )
/* return the Unix pid to use in ptrace calls for a given thread */
int get_ptrace_pid( struct thread *thread )
{
if (thread->unix_tid != -1) return thread->unix_tid;
return thread->unix_pid;
}
@ -150,10 +157,13 @@ int send_thread_signal( struct thread *thread, int sig )
if (thread->unix_pid != -1)
{
ret = kill( thread->unix_pid, sig );
if (thread->unix_tid != -1) ret = tkill( thread->unix_tid, sig );
else ret = kill( thread->unix_pid, sig );
if (ret == -1 && errno == ESRCH) /* thread got killed */
{
thread->unix_pid = -1;
thread->unix_tid = -1;
thread->attached = 0;
}
}
@ -167,7 +177,7 @@ static int attach_thread( struct thread *thread )
if (!use_ptrace) return 0;
if (ptrace( PTRACE_ATTACH, get_ptrace_pid(thread), 0, 0 ) == -1)
{
if (errno == ESRCH) thread->unix_pid = -1; /* thread got killed */
if (errno == ESRCH) thread->unix_pid = thread->unix_tid = -1; /* thread got killed */
return 0;
}
if (debug_level) fprintf( stderr, "%04x: *attached*\n", thread->id );

View File

@ -109,6 +109,7 @@ inline static void init_thread_structure( struct thread *thread )
int i;
thread->unix_pid = -1; /* not known yet */
thread->unix_tid = -1; /* not known yet */
thread->context = NULL;
thread->teb = NULL;
thread->mutex = NULL;
@ -253,8 +254,8 @@ static void dump_thread( struct object *obj, int verbose )
struct thread *thread = (struct thread *)obj;
assert( obj->ops == &thread_ops );
fprintf( stderr, "Thread id=%04x unix pid=%d teb=%p state=%d\n",
thread->id, thread->unix_pid, thread->teb, thread->state );
fprintf( stderr, "Thread id=%04x unix pid=%d unix tid=%d teb=%p state=%d\n",
thread->id, thread->unix_pid, thread->unix_tid, thread->teb, thread->state );
}
static int thread_signaled( struct object *obj, struct thread *thread )
@ -283,9 +284,11 @@ struct thread *get_thread_from_handle( obj_handle_t handle, unsigned int access
/* find a thread from a Unix pid */
struct thread *get_thread_from_pid( int pid )
{
struct thread *t = first_thread;
while (t && (t->unix_pid != pid)) t = t->next;
return t;
struct thread *t;
for (t = first_thread; t; t = t->next) if (t->unix_tid == pid) return t;
for (t = first_thread; t; t = t->next) if (t->unix_pid == pid) return t;
return NULL;
}
/* set all information about a thread */
@ -845,6 +848,7 @@ DECL_HANDLER(init_thread)
if (!current->reply_fd || !current->wait_fd) return;
current->unix_pid = req->unix_pid;
current->unix_tid = req->unix_tid;
current->teb = req->teb;
if (current->suspend + current->process->suspend > 0) stop_thread( current );

View File

@ -86,6 +86,7 @@ struct thread
int attached; /* is thread attached with ptrace? */
int exit_code; /* thread exit code */
int unix_pid; /* Unix pid of client */
int unix_tid; /* Unix tid of client */
CONTEXT *context; /* current context if in an exception handler */
void *teb; /* TEB address (in client address space) */
int priority; /* priority level */
@ -136,6 +137,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 void *get_thread_ip( struct thread *thread );
extern int get_thread_single_step( struct thread *thread );
extern int tkill( int pid, int sig );
extern int send_thread_signal( struct thread *thread, int sig );
extern unsigned int global_error; /* global error code for when no thread is current */

View File

@ -459,6 +459,7 @@ static void dump_init_process_done_reply( const struct init_process_done_reply *
static void dump_init_thread_request( const struct init_thread_request *req )
{
fprintf( stderr, " unix_pid=%d,", req->unix_pid );
fprintf( stderr, " unix_tid=%d,", req->unix_tid );
fprintf( stderr, " teb=%p,", req->teb );
fprintf( stderr, " entry=%p,", req->entry );
fprintf( stderr, " reply_fd=%d,", req->reply_fd );