retval = p->pid;
if (p->real_parent != p->parent) {
write_lock_irq(&tasklist_lock);
- __ptrace_unlink(p);
- do_notify_parent(p, p->exit_signal);
- p->state = TASK_ZOMBIE;
+ /* Double-check with lock held. */
+ if (p->real_parent != p->parent) {
- __ptrace_unlink(p);
++ __ptrace_unlink(p);
+ do_notify_parent(
+ p, p->exit_signal);
- p->state = TASK_ZOMBIE;
++ p->state = TASK_ZOMBIE;
+ p = NULL;
+ }
write_unlock_irq(&tasklist_lock);
- } else
+ }
+ if (p != NULL)
release_task(p);
goto end_wait4;
default:
break;
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+ /*
+ * If there is a group stop in progress,
+ * we must participate in the bookkeeping.
+ */
+ if (current->sig->group_stop_count > 0) {
+ spin_lock_irq(¤t->sig->siglock);
+ --current->sig->group_stop_count;
+ spin_unlock_irq(¤t->sig->siglock);
+ }
+
/* Let the debugger run. */
current->exit_code = signr;
+ current->last_siginfo = info;
set_current_state(TASK_STOPPED);
notify_parent(current, SIGCHLD);
schedule();
continue;
current->exit_code = 0;
- /* Update the siginfo structure. Is this good? */
- /* The debugger continued. Ignore SIGSTOP. */
- if (signr == SIGSTOP)
- continue;
-
+ /* Update the siginfo structure if the signal has
+ changed. If the debugger wanted something
+ specific in the siginfo structure then it should
+ have updated *info via PTRACE_SETSIGINFO. */
if (signr != info->si_signo) {
info->si_signo = signr;
info->si_errno = 0;