Avoid SIGSTOP/SIGCONT race when ptrace is disabled.

Fixed context flags handling (thanks to Eric Pouech).
This commit is contained in:
Alexandre Julliard 2000-03-15 19:47:44 +00:00
parent 98aacc7751
commit cd8cf5e7c5
1 changed files with 18 additions and 22 deletions

View File

@ -138,8 +138,9 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE
if (flags & CONTEXT_FULL) if (flags & CONTEXT_FULL)
{ {
struct kernel_user_regs_struct regs; struct kernel_user_regs_struct regs;
if ((flags & CONTEXT_FULL) != CONTEXT_FULL) /* need to preserve some registers */ if (((flags | CONTEXT_i386) & CONTEXT_FULL) != CONTEXT_FULL)
{ {
/* need to preserve some registers */
if (ptrace( PTRACE_GETREGS, pid, 0, &regs ) == -1) goto error; if (ptrace( PTRACE_GETREGS, pid, 0, &regs ) == -1) goto error;
} }
if (flags & CONTEXT_INTEGER) if (flags & CONTEXT_INTEGER)
@ -250,8 +251,9 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE
if (flags & CONTEXT_FULL) if (flags & CONTEXT_FULL)
{ {
struct regs regs; struct regs regs;
if ((flags & CONTEXT_FULL) != CONTEXT_FULL) /* need to preserve some registers */ if (((flags | CONTEXT_i386) & CONTEXT_FULL) != CONTEXT_FULL)
{ {
/* need to preserve some registers */
if (ptrace( PTRACE_GETREGS, pid, 0, (int) &regs ) == -1) goto error; if (ptrace( PTRACE_GETREGS, pid, 0, (int) &regs ) == -1) goto error;
} }
if (flags & CONTEXT_INTEGER) if (flags & CONTEXT_INTEGER)
@ -358,8 +360,9 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE
if (flags & CONTEXT_FULL) if (flags & CONTEXT_FULL)
{ {
struct reg regs; struct reg regs;
if ((flags & CONTEXT_FULL) != CONTEXT_FULL) /* need to preserve some registers */ if (((flags | CONTEXT_i386) & CONTEXT_FULL) != CONTEXT_FULL)
{ {
/* need to preserve some registers */
if (ptrace( PTRACE_GETREGS, pid, 0, (int) &regs ) == -1) goto error; if (ptrace( PTRACE_GETREGS, pid, 0, (int) &regs ) == -1) goto error;
} }
if (flags & CONTEXT_INTEGER) if (flags & CONTEXT_INTEGER)
@ -438,37 +441,30 @@ static void copy_context( CONTEXT *to, CONTEXT *from, int flags )
to->SegFs = from->SegFs; to->SegFs = from->SegFs;
to->SegGs = from->SegGs; to->SegGs = from->SegGs;
} }
if (flags & CONTEXT_DEBUG_REGISTERS)
{
to->Dr0 = from->Dr0;
to->Dr1 = from->Dr1;
to->Dr2 = from->Dr2;
to->Dr3 = from->Dr3;
to->Dr6 = from->Dr6;
to->Dr7 = from->Dr7;
}
if (flags & CONTEXT_FLOATING_POINT) if (flags & CONTEXT_FLOATING_POINT)
{ {
to->FloatSave = from->FloatSave; to->FloatSave = from->FloatSave;
} }
/* we don't bother copying the debug registers, since they */
/* always need to be accessed by ptrace anyway */
} }
/* retrieve the current context of a thread */ /* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context) DECL_HANDLER(get_thread_context)
{ {
struct thread *thread; struct thread *thread;
int flags = req->flags & ~CONTEXT_i386; /* get rid of CPU id */
if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT )))
{ {
if (thread->context) /* thread is inside an exception event */ if (thread->context) /* thread is inside an exception event */
{ {
copy_context( &req->context, thread->context, req->flags ); copy_context( &req->context, thread->context, flags );
flags &= CONTEXT_DEBUG_REGISTERS;
} }
else if (flags && suspend_for_ptrace( thread ))
{ {
suspend_thread( thread, 0 ); get_thread_context( thread, flags, &req->context );
if (thread->attached) get_thread_context( thread, req->flags, &req->context );
else set_error( STATUS_ACCESS_DENIED );
resume_thread( thread ); resume_thread( thread );
} }
release_object( thread ); release_object( thread );
@ -480,18 +476,18 @@ DECL_HANDLER(get_thread_context)
DECL_HANDLER(set_thread_context) DECL_HANDLER(set_thread_context)
{ {
struct thread *thread; struct thread *thread;
int flags = req->flags & ~CONTEXT_i386; /* get rid of CPU id */
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT ))) if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
{ {
if (thread->context) /* thread is inside an exception event */ if (thread->context) /* thread is inside an exception event */
{ {
copy_context( thread->context, &req->context, req->flags ); copy_context( thread->context, &req->context, flags );
flags &= CONTEXT_DEBUG_REGISTERS;
} }
else if (flags && suspend_for_ptrace( thread ))
{ {
suspend_thread( thread, 0 ); set_thread_context( thread, flags, &req->context );
if (thread->attached) set_thread_context( thread, req->flags, &req->context );
else set_error( STATUS_ACCESS_DENIED );
resume_thread( thread ); resume_thread( thread );
} }
release_object( thread ); release_object( thread );