diff -pur a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c --- a/arch/um/kernel/process_kern.c 2004-10-26 18:50:23.542150873 +0200 +++ b/arch/um/kernel/process_kern.c 2004-10-26 16:28:43.728794504 +0200 @@ -408,8 +408,6 @@ int singlestepping(void * t) if ( ! (task->ptrace & PT_DTRACE) ) return(0); - task->ptrace &= ~PT_DTRACE; - if (task->thread.singlestep_syscall) return(0); diff -pur a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c --- a/arch/um/kernel/ptrace.c 2004-10-26 18:50:33.677475951 +0200 +++ b/arch/um/kernel/ptrace.c 2004-10-26 16:42:41.613329208 +0200 @@ -24,6 +24,8 @@ */ void ptrace_disable(struct task_struct *child) { + child->ptrace &= ~PT_DTRACE; + child->thread.singlestep_syscall = 0; } long sys_ptrace(long request, long pid, long addr, long data) @@ -143,6 +145,8 @@ long sys_ptrace(long request, long pid, ret = -EIO; if ((unsigned long) data > _NSIG) break; + child->ptrace &= ~PT_DTRACE; + child->thread.singlestep_syscall = 0; if (request == PTRACE_SYSCALL) { set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); } @@ -164,6 +168,8 @@ long sys_ptrace(long request, long pid, ret = 0; if (child->state == TASK_ZOMBIE) /* already dead */ break; + child->ptrace &= ~PT_DTRACE; + child->thread.singlestep_syscall = 0; child->exit_code = SIGKILL; wake_up_process(child); break; @@ -175,6 +181,7 @@ long sys_ptrace(long request, long pid, break; clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->ptrace |= PT_DTRACE; + child->thread.singlestep_syscall = 0; child->exit_code = data; /* give it a chance to run. */ wake_up_process(child); @@ -303,6 +310,8 @@ long sys_ptrace(long request, long pid, void syscall_trace(union uml_pt_regs *regs, int entryexit) { + int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit; + if (unlikely(current->audit_context)) { if (!entryexit) audit_syscall_entry(current, regs->orig_eax, @@ -312,15 +321,16 @@ void syscall_trace(union uml_pt_regs *re audit_syscall_exit(current, regs->eax); } - if (!test_thread_flag(TIF_SYSCALL_TRACE)) + if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_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) - ? SYSCALL_TRAP : 0)); + ptrace_notify(SIGTRAP | (((current->ptrace & PT_TRACESYSGOOD) && + !is_singlestep) ? SYSCALL_TRAP : 0)); + set_thread_flag(TIF_SIGPENDING); /* force do_signal() --> is_syscall() */ /* * this isn't the same as continuing with a signal, but it will do diff -pur a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c --- a/arch/um/kernel/signal_kern.c 2004-10-26 18:49:53.885051881 +0200 +++ b/arch/um/kernel/signal_kern.c 2004-10-26 18:25:13.287729206 +0200 @@ -133,9 +133,9 @@ static int kern_do_signal(struct pt_regs * on the host. The tracing thread will check this flag and * PTRACE_SYSCALL if necessary. */ - if((current->ptrace & PT_DTRACE) && - is_syscall(PT_REGS_IP(¤t->thread.regs))) - current->thread.singlestep_syscall = 1; + if(current->ptrace & PT_DTRACE) + current->thread.singlestep_syscall = + is_syscall(PT_REGS_IP(¤t->thread.regs)); return(handled_sig); } diff -pur a/arch/um/kernel/skas/syscall_kern.c b/arch/um/kernel/skas/syscall_kern.c --- a/arch/um/kernel/skas/syscall_kern.c 2004-10-26 18:50:23.542150873 +0200 +++ b/arch/um/kernel/skas/syscall_kern.c 2004-10-26 18:22:46.885922957 +0200 @@ -28,11 +28,6 @@ long execute_syscall_skas(void *r) res = -ENOSYS; else res = EXECUTE_SYSCALL(syscall, regs); - if(current->thread.singlestep_syscall){ - current->thread.singlestep_syscall = 0; - force_sig(SIGTRAP, current); - } - return(res); } diff -pur a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c --- a/arch/um/kernel/tt/syscall_kern.c 2004-10-26 18:50:23.543150707 +0200 +++ b/arch/um/kernel/tt/syscall_kern.c 2004-10-26 18:23:19.266571866 +0200 @@ -30,11 +30,6 @@ long execute_syscall_tt(void *r) res = -ENOSYS; else res = EXECUTE_SYSCALL(syscall, regs); - if(current->thread.singlestep_syscall){ - current->thread.singlestep_syscall = 0; - force_sig(SIGTRAP, current); - } - return(res); } diff -pur a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c --- a/arch/um/sys-i386/signal.c 2004-10-26 18:49:53.870054359 +0200 +++ b/arch/um/sys-i386/signal.c 2004-10-26 18:13:34.805157517 +0200 @@ -4,6 +4,7 @@ */ #include "linux/signal.h" +#include "linux/ptrace.h" #include "asm/current.h" #include "asm/ucontext.h" #include "asm/uaccess.h" @@ -244,6 +245,9 @@ int setup_signal_stack_sc(unsigned long PT_REGS_EAX(regs) = (unsigned long) sig; PT_REGS_EDX(regs) = (unsigned long) 0; PT_REGS_ECX(regs) = (unsigned long) 0; + + if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) + ptrace_notify(SIGTRAP); return(0); } @@ -292,6 +296,8 @@ int setup_signal_stack_si(unsigned long PT_REGS_EDX(regs) = (unsigned long) &frame->info; PT_REGS_ECX(regs) = (unsigned long) &frame->uc; + if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) + ptrace_notify(SIGTRAP); return(0); }