Change ptrace_report_signal() to report SIGTRAP via user_single_step_siginfo() + force_sig_info().
--- kernel/ptrace.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) --- PU/kernel/ptrace.c~132_USER_SINGLE_STEP_INFO 2009-11-13 22:35:40.000000000 +0100 +++ PU/kernel/ptrace.c 2009-11-13 22:44:10.000000000 +0100 @@ -451,16 +451,10 @@ static u32 ptrace_report_exec(enum utrac return UTRACE_STOP; } -static void fill_sigtrap_info(struct task_struct *task, siginfo_t *info) +static void ptrace_send_sigtrap(struct task_struct *task, siginfo_t *info) { -#ifdef CONFIG_X86 - task->thread.trap_no = 1; - task->thread.error_code = 0; -#endif - memset(info, 0, sizeof(*info)); - info->si_signo = SIGTRAP; - info->si_code = TRAP_BRKPT; - info->si_addr = (void __user*)KSTK_EIP(task); + user_single_step_siginfo(task, task_pt_regs(task), info); + force_sig_info(SIGTRAP, info, task); } static enum utrace_signal_action resume_signal(struct task_struct *task, @@ -534,13 +528,13 @@ static u32 ptrace_report_signal(u32 acti case UTRACE_SIGNAL_REPORT: if (!ctx->siginfo) { - if (!ctx->signr) - return resume | UTRACE_SIGNAL_IGN; + if (ctx->signr) { + /* set by ptrace_resume(SYSCALL_EXIT) */ + WARN_ON(ctx->signr != SIGTRAP); + ptrace_send_sigtrap(task, info); + } - WARN_ON(ctx->signr != SIGTRAP); - /* set by ptrace_resume(PTRACE_EVENT_SYSCALL_EXIT) */ - fill_sigtrap_info(task, info); - break; + return resume | UTRACE_SIGNAL_IGN; } if (WARN_ON(ctx->siginfo != info))