Kill utrace_report->killed and change the only user, utrace_get_signal(),
to use fatal_signal_pending().

Similarly, change utrace_report_syscall_entry(), noe it is the only caller
of utrace_stop() which checks the returned value.

The boolean returned by utrace_stop()->finish_utrace_stop() is not very
accurate. utrace_wakeup() can clear utrace->stopped but not wake up if
SIGNAL_STOP_STOPPED. The tracee can sleep for a long time, then it can
be SIGKILLED but in this case finish_utrace_stop() misses SIGKILL.

Signed-off-by: Oleg Nesterov <o...@redhat.com>
---

 kernel/utrace.c |   19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

--- __UTRACE/kernel/utrace.c~2_KILL_KILLED      2009-08-14 12:43:44.000000000 
+0200
+++ __UTRACE/kernel/utrace.c    2009-08-14 13:26:51.000000000 +0200
@@ -1262,12 +1262,12 @@ struct utrace_report {
        bool detaches;
        bool reports;
        bool takers;
-       bool killed;
 };
 
 #define INIT_REPORT(var) \
-       struct utrace_report var = { UTRACE_RESUME, 0, \
-                                    false, false, false, false }
+       struct utrace_report var = {            \
+               .action = UTRACE_RESUME,        \
+       }
 
 /*
  * We are now making the report, so clear the flag saying we need one.
@@ -1502,14 +1502,15 @@ bool utrace_report_syscall_entry(struct 
                         report.result | report.action, engine, current, regs);
        finish_report(&report, task, utrace);
 
-       if (report.action == UTRACE_STOP &&
-           unlikely(utrace_stop(task, utrace, false)))
+       if (report.action == UTRACE_STOP) {
+               utrace_stop(task, utrace, false);
                /*
                 * We are continuing despite UTRACE_STOP because of a
                 * SIGKILL.  Don't let the system call actually proceed.
                 */
-               return true;
-
+               if (unlikely(fatal_signal_pending(task)))
+                       return true;
+       }
        return report.result == UTRACE_SYSCALL_ABORT;
 }
 
@@ -1707,7 +1708,7 @@ static void finish_resume_report(struct 
 
        switch (report->action) {
        case UTRACE_STOP:
-               report->killed = utrace_stop(task, utrace, report->reports);
+               utrace_stop(task, utrace, report->reports);
                break;
 
        case UTRACE_INTERRUPT:
@@ -2109,7 +2110,7 @@ int utrace_get_signal(struct task_struct
                 */
                finish_resume_report(&report, task, utrace);
 
-               if (unlikely(report.killed)) {
+               if (unlikely(fatal_signal_pending(task))) {
                        /*
                         * The only reason we woke up now was because of a
                         * SIGKILL.  Don't do normal dequeuing in case it

Reply via email to