exit_notify: fix kill_orphaned_pgrp() usage with mt exit
1. exit_notify() always calls kill_orphaned_pgrp(). This is wrong, we should do this only when the whole process exits. 2. exit_notify() uses "current" as "ignored_task", obviously wrong. Use ->group_leader instead. Test case: void hup(int sig) { printf("HUP received\n"); } void *tfunc(void *arg) { sleep(2); printf("sub-thread exited\n"); return NULL; } int main(int argc, char *argv[]) { if (!fork()) { signal(SIGHUP, hup); kill(getpid(), SIGSTOP); exit(0); } pthread_t thr; pthread_create(&thr, NULL, tfunc, NULL); sleep(1); printf("main thread exited\n"); syscall(__NR_exit, 0); return 0; } output: main thread exited HUP received Hangup With this patch the output is: main thread exited sub-thread exited HUP received Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
05e83df624
commit
821c7de719
@ -750,7 +750,7 @@ static void forget_original_parent(struct task_struct *father)
|
|||||||
* Send signals to all our closest relatives so that they know
|
* Send signals to all our closest relatives so that they know
|
||||||
* to properly mourn us..
|
* to properly mourn us..
|
||||||
*/
|
*/
|
||||||
static void exit_notify(struct task_struct *tsk)
|
static void exit_notify(struct task_struct *tsk, int group_dead)
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
@ -766,7 +766,8 @@ static void exit_notify(struct task_struct *tsk)
|
|||||||
exit_task_namespaces(tsk);
|
exit_task_namespaces(tsk);
|
||||||
|
|
||||||
write_lock_irq(&tasklist_lock);
|
write_lock_irq(&tasklist_lock);
|
||||||
kill_orphaned_pgrp(tsk, NULL);
|
if (group_dead)
|
||||||
|
kill_orphaned_pgrp(tsk->group_leader, NULL);
|
||||||
|
|
||||||
/* Let father know we died
|
/* Let father know we died
|
||||||
*
|
*
|
||||||
@ -981,7 +982,7 @@ NORET_TYPE void do_exit(long code)
|
|||||||
module_put(tsk->binfmt->module);
|
module_put(tsk->binfmt->module);
|
||||||
|
|
||||||
proc_exit_connector(tsk);
|
proc_exit_connector(tsk);
|
||||||
exit_notify(tsk);
|
exit_notify(tsk, group_dead);
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
mpol_free(tsk->mempolicy);
|
mpol_free(tsk->mempolicy);
|
||||||
tsk->mempolicy = NULL;
|
tsk->mempolicy = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user