Messages in this thread Patch in this message | | | Date | Sun, 18 Sep 2005 17:22:32 -0600 (MDT) | From | "Bhavesh P. Davda" <> | Subject | [PATCH] Show Mr. SIGKILL some R-E-S-P-E-C-T |
| |
Here's the scenario (single-threaded, multi-threaded doesn't matter)
# kill -STOP pid # egrep "^State|^SigPnd|^ShdPnd" /proc/pid/status State: T (stopped) SigPnd: 0000000000000000 ShdPnd: 0000000000000000
The following command sends a signal to the specified thread ID using the tkill(2) syscall interface
# tkill -ALRM pid (Or any other signal other than SIGCONT or SIGKILL) # egrep "^State|^SigPnd|^ShdPnd" /proc/pid/status State: T (stopped) SigPnd: 0000000000002000 [ SIGALRM pending ] ShdPnd: 0000000000000000
# kill -ABRT pid # egrep "^State|^SigPnd|^ShdPnd" /proc/pid/status State: T (stopped) SigPnd: 0000000000002000 [ SIGALRM pending ] ShdPnd: 0000000000000020 [ SIGABRT pending ]
# kill -KILL pid # egrep "^State|^SigPnd|^ShdPnd" /proc/pid/status State: T (stopped) SigPnd: 0000000000002000 [ SIGALRM pending ] ShdPnd: 0000000000000120 [ SIGABRT and SIGKILL pending ]
EGAD! SIGKILL should have whacked the pid, no matter what.
Here's a patch that fixes this.
Thanks!
- Bhavesh
Bhavesh P. Davda | Distinguished Member of Technical Staff | Avaya | 1300 West 120th Avenue | B3-B03 | Westminster, CO 80234 | U.S.A. | Voice/Fax: 303.538.4438 | bhavesh@avaya.com --- a/kernel/signal.c 2005-09-12 15:50:16.000000000 -0600 +++ b/kernel/signal.c 2005-09-17 12:04:58.898465728 -0600 @@ -935,10 +935,11 @@ * have pending signals. Such threads will dequeue from the shared queue * as soon as they're available, so putting the signal on the shared queue * will be equivalent to sending it to one such thread. + * Don't bother traced and stopped tasks */ -#define wants_signal(sig, p, mask) \ +#define wants_signal(sig, p) \ (!sigismember(&(p)->blocked, sig) \ - && !((p)->state & mask) \ + && !((p)->state & (TASK_STOPPED|TASK_TRACED)) \ && !((p)->flags & PF_EXITING) \ && (task_curr(p) || !signal_pending(p))) @@ -946,24 +947,17 @@ static void __group_complete_signal(int sig, struct task_struct *p) { - unsigned int mask; struct task_struct *t; /* - * Don't bother traced and stopped tasks (but - * SIGKILL will punch through that). - */ - mask = TASK_STOPPED | TASK_TRACED; - if (sig == SIGKILL) - mask = 0; - - /* * Now find a thread we can wake up to take the signal off the queue. * * If the main thread wants the signal, it gets first crack. * Probably the least surprising to the average bear. + * + * SIGKILL is always delivered to the main thread */ - if (wants_signal(sig, p, mask)) + if ((sig == SIGKILL) || (wants_signal(sig, p))) t = p; else if (thread_group_empty(p)) /* @@ -981,7 +975,7 @@ t = p->signal->curr_target = p; BUG_ON(t->tgid != p->tgid); - while (!wants_signal(sig, t, mask)) { + while (!wants_signal(sig, t)) { t = next_thread(t); if (t == p->signal->curr_target) /*
| |