Commit ada73838 authored by Ove Kaaven's avatar Ove Kaaven Committed by Alexandre Julliard

Preserve the TF (Trap Flag) when continuing from a ptraced suspend.

parent 15a3b743
...@@ -474,6 +474,15 @@ void *get_thread_ip( struct thread *thread ) ...@@ -474,6 +474,15 @@ void *get_thread_ip( struct thread *thread )
return (void *)context.Eip; return (void *)context.Eip;
} }
/* determine if we should continue the thread in single-step mode */
int get_thread_single_step( struct thread *thread )
{
CONTEXT context;
if (thread->context) return 0; /* don't single-step inside exception event */
get_thread_context( thread, CONTEXT_CONTROL, &context );
return (context.EFlags & 0x100) != 0;
}
/* retrieve the current context of a thread */ /* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context) DECL_HANDLER(get_thread_context)
{ {
......
...@@ -157,6 +157,12 @@ void *get_thread_ip( struct thread *thread ) ...@@ -157,6 +157,12 @@ void *get_thread_ip( struct thread *thread )
return (void *)context.pc; return (void *)context.pc;
} }
/* determine if we should continue the thread in single-step mode */
int get_thread_single_step( struct thread *thread )
{
return 0; /* FIXME */
}
/* retrieve the current context of a thread */ /* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context) DECL_HANDLER(get_thread_context)
{ {
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
#ifndef PTRACE_CONT #ifndef PTRACE_CONT
#define PTRACE_CONT PT_CONTINUE #define PTRACE_CONT PT_CONTINUE
#endif #endif
#ifndef PTRACE_SINGLESTEP
#define PTRACE_SINGLESTEP PT_STEP
#endif
#ifndef PTRACE_ATTACH #ifndef PTRACE_ATTACH
#define PTRACE_ATTACH PT_ATTACH #define PTRACE_ATTACH PT_ATTACH
#endif #endif
...@@ -49,6 +52,7 @@ static const int use_ptrace = 0; ...@@ -49,6 +52,7 @@ static const int use_ptrace = 0;
#define PT_DETACH 2 #define PT_DETACH 2
#define PT_READ_D 3 #define PT_READ_D 3
#define PT_WRITE_D 4 #define PT_WRITE_D 4
#define PT_STEP 5
static int ptrace(int req, ...) { return -1; /*FAIL*/ } static int ptrace(int req, ...) { return -1; /*FAIL*/ }
#endif #endif
...@@ -64,10 +68,12 @@ static int handle_child_status( struct thread *thread, int pid, int status ) ...@@ -64,10 +68,12 @@ static int handle_child_status( struct thread *thread, int pid, int status )
switch(sig) switch(sig)
{ {
case SIGSTOP: /* continue at once if not suspended */ case SIGSTOP: /* continue at once if not suspended */
if (!thread || !(thread->process->suspend + thread->suspend)) if (thread && (thread->process->suspend + thread->suspend)) break;
ptrace( PTRACE_CONT, pid, (caddr_t)1, sig ); /* fall through */
break;
default: /* ignore other signals for now */ default: /* ignore other signals for now */
if (thread && get_thread_single_step( thread ))
ptrace( PTRACE_SINGLESTEP, pid, (caddr_t)1, sig );
else
ptrace( PTRACE_CONT, pid, (caddr_t)1, sig ); ptrace( PTRACE_CONT, pid, (caddr_t)1, sig );
break; break;
} }
...@@ -168,7 +174,8 @@ void continue_thread( struct thread *thread ) ...@@ -168,7 +174,8 @@ void continue_thread( struct thread *thread )
{ {
if (!thread->unix_pid) return; if (!thread->unix_pid) return;
if (!thread->attached) kill( thread->unix_pid, SIGCONT ); if (!thread->attached) kill( thread->unix_pid, SIGCONT );
else ptrace( PTRACE_CONT, thread->unix_pid, (caddr_t)1, SIGSTOP ); else ptrace( get_thread_single_step(thread) ? PTRACE_SINGLESTEP : PTRACE_CONT,
thread->unix_pid, (caddr_t)1, SIGSTOP );
} }
/* suspend a thread to allow using ptrace on it */ /* suspend a thread to allow using ptrace on it */
......
...@@ -118,6 +118,7 @@ extern int suspend_for_ptrace( struct thread *thread ); ...@@ -118,6 +118,7 @@ extern int suspend_for_ptrace( struct thread *thread );
extern int read_thread_int( struct thread *thread, const int *addr, int *data ); 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 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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment