rt_sigtimedwait: could not wait for ignored signal

Change-Id: I0f5a8e2eaae2b7c08a01f4ebb2c405b8972269a2
Refs: #1378
This commit is contained in:
Tomoki Shirasawa
2020-02-05 09:43:47 +09:00
committed by Masamichi Takagi
parent 41ea9d16c4
commit cafb46efc7
2 changed files with 54 additions and 72 deletions

View File

@ -1619,7 +1619,6 @@ do_kill(struct thread * thread, int pid, int tid, int sig, siginfo_t *info, int
struct list_head *head = NULL; struct list_head *head = NULL;
int rc; int rc;
unsigned long irqstate = 0; unsigned long irqstate = 0;
struct k_sigaction *k;
int doint; int doint;
int found = 0; int found = 0;
siginfo_t info0; siginfo_t info0;
@ -1629,6 +1628,7 @@ do_kill(struct thread * thread, int pid, int tid, int sig, siginfo_t *info, int
struct process_hash *phash = rset->process_hash; struct process_hash *phash = rset->process_hash;
struct mcs_rwlock_node lock; struct mcs_rwlock_node lock;
struct mcs_rwlock_node updatelock; struct mcs_rwlock_node updatelock;
struct sig_pending *pending = NULL;
if(sig > SIGRTMAX || sig < 0) if(sig > SIGRTMAX || sig < 0)
return -EINVAL; return -EINVAL;
@ -1815,46 +1815,36 @@ done:
mcs_rwlock_writer_lock_noirq(savelock, &mcs_rw_node); mcs_rwlock_writer_lock_noirq(savelock, &mcs_rw_node);
/* Put signal event even when handler is SIG_IGN or SIG_DFL
because target ptraced thread must call ptrace_report_signal
in check_signal */
rc = 0; rc = 0;
k = tthread->sigcommon->action + sig - 1;
if ((sig != SIGKILL && (tthread->ptrace & PT_TRACED)) || if (sig < SIGRTMIN) { // SIGRTMIN - SIGRTMAX
(k->sa.sa_handler != SIG_IGN && list_for_each_entry(pending, head, list) {
(k->sa.sa_handler != NULL || if (pending->sigmask.__val[0] == mask &&
(sig != SIGCHLD && pending->ptracecont == ptracecont)
sig != SIGURG && break;
sig != SIGCONT)))) {
struct sig_pending *pending = NULL;
if (sig < SIGRTMIN) { // SIGRTMIN - SIGRTMAX
list_for_each_entry(pending, head, list){
if(pending->sigmask.__val[0] == mask &&
pending->ptracecont == ptracecont)
break;
}
if(&pending->list == head)
pending = NULL;
} }
if(pending == NULL){ if (&pending->list == head)
doint = 1; pending = NULL;
pending = kmalloc(sizeof(struct sig_pending), IHK_MC_AP_NOWAIT); }
if(!pending){ if (pending == NULL) {
rc = -ENOMEM; doint = 1;
} pending = kmalloc(sizeof(struct sig_pending), IHK_MC_AP_NOWAIT);
else{ if (!pending) {
memset(pending, 0, sizeof(struct sig_pending)); rc = -ENOMEM;
pending->sigmask.__val[0] = mask; }
memcpy(&pending->info, info, sizeof(siginfo_t)); else {
pending->ptracecont = ptracecont; memset(pending, 0, sizeof(struct sig_pending));
if(sig == SIGKILL || sig == SIGSTOP) pending->sigmask.__val[0] = mask;
list_add(&pending->list, head); memcpy(&pending->info, info, sizeof(siginfo_t));
else pending->ptracecont = ptracecont;
list_add_tail(&pending->list, head); if (sig == SIGKILL || sig == SIGSTOP)
tthread->sigevent = 1; list_add(&pending->list, head);
} else
list_add_tail(&pending->list, head);
tthread->sigevent = 1;
} }
} }
mcs_rwlock_writer_unlock_noirq(savelock, &mcs_rw_node); mcs_rwlock_writer_unlock_noirq(savelock, &mcs_rw_node);
cpu_restore_interrupt(irqstate); cpu_restore_interrupt(irqstate);

View File

@ -1313,7 +1313,6 @@ do_kill(struct thread *thread, int pid, int tid, int sig, siginfo_t *info,
struct list_head *head = NULL; struct list_head *head = NULL;
int rc; int rc;
unsigned long irqstate = 0; unsigned long irqstate = 0;
struct k_sigaction *k;
int doint; int doint;
int found = 0; int found = 0;
siginfo_t info0; siginfo_t info0;
@ -1323,6 +1322,7 @@ do_kill(struct thread *thread, int pid, int tid, int sig, siginfo_t *info,
struct process_hash *phash = rset->process_hash; struct process_hash *phash = rset->process_hash;
struct mcs_rwlock_node lock; struct mcs_rwlock_node lock;
struct mcs_rwlock_node updatelock; struct mcs_rwlock_node updatelock;
struct sig_pending *pending = NULL;
if(sig > 64 || sig < 0) if(sig > 64 || sig < 0)
return -EINVAL; return -EINVAL;
@ -1544,44 +1544,36 @@ done:
mcs_rwlock_writer_lock_noirq(savelock, &mcs_rw_node); mcs_rwlock_writer_lock_noirq(savelock, &mcs_rw_node);
/* Put signal event even when handler is SIG_IGN or SIG_DFL
because target ptraced thread must call ptrace_report_signal
in check_signal */
rc = 0; rc = 0;
k = tthread->sigcommon->action + sig - 1;
if ((sig != SIGKILL && (tthread->ptrace & PT_TRACED)) || if (sig < 33) { // SIGRTMIN - SIGRTMAX
(k->sa.sa_handler != (void *)1 && list_for_each_entry(pending, head, list) {
(k->sa.sa_handler != NULL || if (pending->sigmask.__val[0] == mask &&
(sig != SIGCHLD && sig != SIGURG && sig != SIGCONT)))) { pending->ptracecont == ptracecont)
struct sig_pending *pending = NULL; break;
if (sig < 33) { // SIGRTMIN - SIGRTMAX
list_for_each_entry(pending, head, list){
if(pending->sigmask.__val[0] == mask &&
pending->ptracecont == ptracecont)
break;
}
if(&pending->list == head)
pending = NULL;
} }
if(pending == NULL){ if (&pending->list == head)
doint = 1; pending = NULL;
pending = kmalloc(sizeof(struct sig_pending), IHK_MC_AP_NOWAIT); }
if(!pending){ if (pending == NULL) {
rc = -ENOMEM; doint = 1;
} pending = kmalloc(sizeof(struct sig_pending), IHK_MC_AP_NOWAIT);
else{ if (!pending) {
memset(pending, 0, sizeof(struct sig_pending)); rc = -ENOMEM;
pending->sigmask.__val[0] = mask; }
memcpy(&pending->info, info, sizeof(siginfo_t)); else {
pending->ptracecont = ptracecont; memset(pending, 0, sizeof(struct sig_pending));
if(sig == SIGKILL || sig == SIGSTOP) pending->sigmask.__val[0] = mask;
list_add(&pending->list, head); memcpy(&pending->info, info, sizeof(siginfo_t));
else pending->ptracecont = ptracecont;
list_add_tail(&pending->list, head); if (sig == SIGKILL || sig == SIGSTOP)
tthread->sigevent = 1; list_add(&pending->list, head);
} else
list_add_tail(&pending->list, head);
tthread->sigevent = 1;
} }
} }
mcs_rwlock_writer_unlock_noirq(savelock, &mcs_rw_node); mcs_rwlock_writer_unlock_noirq(savelock, &mcs_rw_node);
cpu_restore_interrupt(irqstate); cpu_restore_interrupt(irqstate);