[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