Q: utrace && ptrace_check_attach()
Oleg Nesterov
oleg at redhat.com
Thu Jul 23 19:34:14 UTC 2009
On 07/22, Roland McGrath wrote:
>
> > This means ptrace_check_attach() can succeed but the tracee can even return
> > to the user-space after that, no? There is no guarantee utrace_get_signal()
> > will call finish_resume_report(). For example, if there are no pending
> > signals, we just clear ->stopped and return after dequeue_signal().
>
> Yes, I think you're right. I think the "if (unlikely(utrace->stopped)) {"
> case in utrace_get_signal() needs to do some variant of utrace_reset. If
> any engine_wants_stop() then it should not dequeue a signal even if one is
> ready, and probably it should also not do any spontaneous report.
Hmm. If ->stopped == T after return from do_signal_stop()->schedule(),
then we must have the engine which is engine_wants_stop(), no?
> OTOH perhaps it should do a spontaneous report in that case, so that if you
> used utrace_control(,,UTRACE_STOP) while in TASK_STOPPED, you get a
> UTRACE_SIGNAL_REPORT callback at SIGCONT time. If that's the plan, then
> all we need is utrace_do_stop()'s task_is_stopped() case to set ->report
> too (and set_notify_resume for the invariant, though it's superfluous really).
Damn. Just can't think today...
Roland, can we just remove all code which plays with ->stopped in
utrace_report_jctl() and utrace_get_signal(), and do something like
--- kernel/utrace.c
+++ kernel/utrace.c
@@ -390,6 +390,13 @@ static bool utrace_stop(struct task_stru
* for stop signals and SIGCONT.
*/
spin_lock(&utrace->lock);
+
+ return utrace_stop_locked(task, utrace, report);
+}
+
+bool utrace_stop_locked(struct task_struct *task, struct utrace *utrace,
+ bool report)
+{
spin_lock_irq(&task->sighand->siglock);
if (unlikely(sigismember(&task->pending.signal, SIGKILL))) {
--- kernel/signal.c
+++ kernel/signal.c
@@ -1602,6 +1602,16 @@ static int do_signal_stop(int signr)
do {
schedule();
} while (try_to_freeze());
+
+ // needs a tracehook helper
+ if (utrace->stopped) {
+ spin_lock(&utrace->lock);
+ if (utrace->stopped)
+ utrace_stop_locked();
+ else
+ spin_unlock(&utrace->lock);
+ }
+
/*
* Now we don't run again until continued.
*/
No?
Oleg.
More information about the utrace-devel
mailing list