[PATCH 27] convert ptrace_report_syscall_exit() to use ptrace_context
Oleg Nesterov
oleg at redhat.com
Mon Sep 7 22:04:12 UTC 2009
Convert ptrace_report_syscall_exit() to use ptrace_context.
Incomplete:
- I don't underastand SYSEMU/SINGLESTEP magic yet
- last_siginfo logic is not supported yet, but afaics
the current is wrong too.
---
kernel/ptrace.c | 49 ++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 11 deletions(-)
--- PU/kernel/ptrace.c~27_SYSCALL_EXIT 2009-09-07 22:52:39.000000000 +0200
+++ PU/kernel/ptrace.c 2009-09-07 23:50:50.000000000 +0200
@@ -316,24 +316,51 @@ static u32 ptrace_report_vfork_done(stru
task->ptrace_message);
}
+static void ptrace_wake_up(struct utrace_engine *engine,
+ struct task_struct *tracee,
+ enum utrace_resume_action action)
+{
+ /* preserve the compatibility bug */
+ if (task_is_stopped(tracee)) {
+ spin_lock_irq(&tracee->sighand->siglock);
+ tracee->signal->flags &= ~SIGNAL_STOP_STOPPED;
+ spin_unlock_irq(&tracee->sighand->siglock);
+ }
+
+ // XXX: FIXME!!! racy.
+ tracee->exit_code = 0;
+
+ utrace_control(tracee, engine, action);
+}
+
+static void ptrace_resume_syscall(struct utrace_engine *engine,
+ struct task_struct *tracee, long data)
+{
+ if (data) {
+ // XXX: until do_send_sig_info()
+ read_lock(&tasklist_lock);
+ if (tracee->signal)
+ send_sig(data, tracee, 1);
+ read_unlock(&tasklist_lock);
+ }
+
+ ptrace_wake_up(engine, tracee, UTRACE_RESUME);
+}
+
static u32 ptrace_report_syscall_exit(enum utrace_resume_action action,
struct utrace_engine *engine,
struct task_struct *task,
struct pt_regs *regs)
{
- if (unlikely(ptrace_stop_event(task) == PTRACE_EVENT_VFORK))
- return ptrace_report_vfork_done(task);
+ struct ptrace_context *context = ptrace_context(engine);
- if (unlikely(ptrace_syscall_action(task)) &&
- unlikely(ptrace_resume_action(task) == UTRACE_SINGLESTEP))
- /*
- * This is PTRACE_SYSEMU_SINGLESTEP.
- * Kludge: Prevent arch code from sending a SIGTRAP
- * after tracehook_report_syscall_exit() returns.
- */
- user_disable_single_step(task);
+ WARN_ON(context->resume_stopped);
+ WARN_ON(context->stopped_code);
- return ptrace_report_syscall(0, engine, task);
+ context->resume_stopped = ptrace_resume_syscall;
+ context->stopped_code = (context->options & PTRACE_O_TRACESYSGOOD) ?
+ (SIGTRAP | 0x80) : SIGTRAP;
+ return action | UTRACE_STOP;
}
static u32 ptrace_resumed(struct task_struct *task,
More information about the utrace-devel
mailing list