Kill PTRACE_EVENT_SIGTRAP state, report PTRACE_EVENT_SIGNAL with the valid ctx->siginfo instead.
Note: we can change ptrace_report_exec() to set ->signr = SIGTRAP and return UTRACE_INTERRUPT too, instead of send_sig(SIGTRAP). We can even change ptrace_resume(PTRACE_EVENT_SIGNAL) similarly, but this needs more efforts. --- kernel/ptrace.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) --- PU/kernel/ptrace.c~129_KILL_PTRACE_EVENT_SIGTRAP 2009-11-02 06:16:53.000000000 +0100 +++ PU/kernel/ptrace.c 2009-11-02 06:54:49.000000000 +0100 @@ -73,8 +73,7 @@ struct ptrace_context { #define PTRACE_EVENT_SYSCALL_ENTRY (1 << 16) #define PTRACE_EVENT_SYSCALL_EXIT (2 << 16) -#define PTRACE_EVENT_SIGTRAP (3 << 16) -#define PTRACE_EVENT_SIGNAL (4 << 16) +#define PTRACE_EVENT_SIGNAL (3 << 16) /* events visible to user-space */ #define PTRACE_EVENT_MASK 0xFFFF @@ -525,9 +524,12 @@ static u32 ptrace_report_signal(u32 acti ctx->siginfo = NULL; if (resume != UTRACE_RESUME) { - set_stop_code(ctx, PTRACE_EVENT_SIGTRAP); - return UTRACE_STOP | UTRACE_SIGNAL_IGN; + WARN_ON(resume != UTRACE_BLOCKSTEP && + resume != UTRACE_SINGLESTEP); + WARN_ON(ctx->signr); + ctx->signr = SIGTRAP; } + /* fallthrough */ case UTRACE_SIGNAL_REPORT: if (!ctx->siginfo) { @@ -535,7 +537,10 @@ static u32 ptrace_report_signal(u32 acti return resume | UTRACE_SIGNAL_IGN; WARN_ON(ctx->signr != SIGTRAP); - /* set by ptrace_resume(PTRACE_EVENT_SYSCALL_EXIT) */ + /* + * set by ptrace_resume(PTRACE_EVENT_SYSCALL_EXIT) or + * by UTRACE_SIGNAL_HANDLER above. + */ fill_sigtrap_info(task, info); break; }