Commit 45cdf5cc0703c537194588c63d53bad1f2539d36

Authored by Oleg Nesterov
1 parent 53c8f9f199

kill tracehook_notify_death()

Kill tracehook_notify_death(), reimplement the logic in its caller,
exit_notify().

Also, change the exec_id's check to use thread_group_leader() instead
of task_detached(), this is more clear. This logic only applies to
the exiting leader, a sub-thread must never change its exit_signal.

Note: when the traced group leader exits the exit_signal-or-SIGCHLD
logic looks really strange:

	- we notify the tracer even if !thread_group_empty() but
	   do_wait(WEXITED) can't work until all threads exit

	- if the tracer is real_parent, it is not clear why can't
	  we use ->exit_signal event if !thread_group_empty()

-v2: do not try to fix the 2nd oddity to avoid the subtle behavior
     change mixed with reorganization, suggested by Tejun.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Tejun Heo <tj@kernel.org>

Showing 2 changed files with 13 additions and 42 deletions Side-by-side Diff

include/linux/tracehook.h
... ... @@ -152,40 +152,6 @@
152 152 ptrace_notify(SIGTRAP);
153 153 }
154 154  
155   -#define DEATH_REAP -1
156   -#define DEATH_DELAYED_GROUP_LEADER -2
157   -
158   -/**
159   - * tracehook_notify_death - task is dead, ready to notify parent
160   - * @task: @current task now exiting
161   - * @death_cookie: value to pass to tracehook_report_death()
162   - * @group_dead: nonzero if this was the last thread in the group to die
163   - *
164   - * A return value >= 0 means call do_notify_parent() with that signal
165   - * number. Negative return value can be %DEATH_REAP to self-reap right
166   - * now, or %DEATH_DELAYED_GROUP_LEADER to a zombie without notifying our
167   - * parent. Note that a return value of 0 means a do_notify_parent() call
168   - * that sends no signal, but still wakes up a parent blocked in wait*().
169   - *
170   - * Called with write_lock_irq(&tasklist_lock) held.
171   - */
172   -static inline int tracehook_notify_death(struct task_struct *task,
173   - void **death_cookie, int group_dead)
174   -{
175   - if (task_detached(task))
176   - return task->ptrace ? SIGCHLD : DEATH_REAP;
177   -
178   - /*
179   - * If something other than our normal parent is ptracing us, then
180   - * send it a SIGCHLD instead of honoring exit_signal. exit_signal
181   - * only has special meaning to our real parent.
182   - */
183   - if (thread_group_empty(task) && !ptrace_reparented(task))
184   - return task->exit_signal;
185   -
186   - return task->ptrace ? SIGCHLD : DEATH_DELAYED_GROUP_LEADER;
187   -}
188   -
189 155 #ifdef TIF_NOTIFY_RESUME
190 156 /**
191 157 * set_notify_resume - cause tracehook_notify_resume() to be called
... ... @@ -819,9 +819,7 @@
819 819 */
820 820 static void exit_notify(struct task_struct *tsk, int group_dead)
821 821 {
822   - int signal;
823 822 bool autoreap;
824   - void *cookie;
825 823  
826 824 /*
827 825 * This does two things:
828 826  
... ... @@ -852,16 +850,23 @@
852 850 * we have changed execution domain as these two values started
853 851 * the same after a fork.
854 852 */
855   - if (tsk->exit_signal != SIGCHLD && !task_detached(tsk) &&
  853 + if (thread_group_leader(tsk) && tsk->exit_signal != SIGCHLD &&
856 854 (tsk->parent_exec_id != tsk->real_parent->self_exec_id ||
857 855 tsk->self_exec_id != tsk->parent_exec_id))
858 856 tsk->exit_signal = SIGCHLD;
859 857  
860   - signal = tracehook_notify_death(tsk, &cookie, group_dead);
861   - if (signal >= 0)
862   - autoreap = do_notify_parent(tsk, signal);
863   - else
864   - autoreap = (signal == DEATH_REAP);
  858 + if (unlikely(tsk->ptrace)) {
  859 + int sig = thread_group_leader(tsk) &&
  860 + thread_group_empty(tsk) &&
  861 + !ptrace_reparented(tsk) ?
  862 + tsk->exit_signal : SIGCHLD;
  863 + autoreap = do_notify_parent(tsk, sig);
  864 + } else if (thread_group_leader(tsk)) {
  865 + autoreap = thread_group_empty(tsk) &&
  866 + do_notify_parent(tsk, tsk->exit_signal);
  867 + } else {
  868 + autoreap = true;
  869 + }
865 870  
866 871 tsk->exit_state = autoreap ? EXIT_DEAD : EXIT_ZOMBIE;
867 872