Preserve the TF (Trap Flag) when continuing from a ptraced suspend.
This commit is contained in:
parent
15a3b74356
commit
ada7383852
@ -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 )
|
|||||||
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 @@
|
|||||||
#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;
|
|||||||
#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 )
|
|||||||
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 )
|
|||||||
{
|
{
|
||||||
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 );
|
|||||||
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 */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user