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]
|
|