X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fi386%2Fkernel%2Fptrace.c;h=58a4f2f1d4e1e01d46c9e0b7fe87fc810e853385;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=6f3a6269408b93e6a30a04069a806137a2e9c0c4;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index 6f3a62694..58a4f2f1d 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -147,6 +147,7 @@ void ptrace_disable(struct task_struct *child) { long tmp; + clear_tsk_thread_flag(child, TIF_SINGLESTEP); tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG; put_stack_long(child, EFL_OFFSET, tmp); } @@ -372,6 +373,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) else { clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); } + clear_tsk_thread_flag(child, TIF_SINGLESTEP); child->exit_code = data; /* make sure the single step bit is not set. */ tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG; @@ -393,6 +395,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if (child->state == TASK_ZOMBIE) /* already dead */ break; child->exit_code = SIGKILL; + clear_tsk_thread_flag(child, TIF_SINGLESTEP); /* make sure the single step bit is not set. */ tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG; put_stack_long(child, EFL_OFFSET, tmp); @@ -413,6 +416,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) } tmp = get_stack_long(child, EFL_OFFSET) | TRAP_FLAG; put_stack_long(child, EFL_OFFSET, tmp); + set_tsk_thread_flag(child, TIF_SINGLESTEP); child->exit_code = data; /* give it a chance to run. */ wake_up_process(child); @@ -537,14 +541,15 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit) audit_syscall_exit(current, regs->eax); } - if (!test_thread_flag(TIF_SYSCALL_TRACE)) + if (!test_thread_flag(TIF_SYSCALL_TRACE) && + !test_thread_flag(TIF_SINGLESTEP)) return; if (!(current->ptrace & PT_PTRACED)) return; /* the 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) && + !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0)); /* * this isn't the same as continuing with a signal, but it will do