[PATCH] Show Mr. SIGKILL some R-E-S-P-E-C-T

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 | [email protected]
--- 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)
 				/*

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux