static void coredump_finish(struct mm_struct *mm, bool core_dumped) { struct core_thread *curr, *next; struct task_struct *task; spin_lock_irq(¤t->sighand->siglock); if (core_dumped && !__fatal_signal_pending(current)) current->signal->group_exit_code |= 0x80; current->signal->group_exit_task = NULL; current->signal->flags = SIGNAL_GROUP_EXIT; spin_unlock_irq(¤t->sighand->siglock); next = mm->core_state->dumper.next; while ((curr = next) != NULL) { next = curr->next; task = curr->task; /* * see exit_mm(), curr->task must not see * ->task == NULL before we read ->next. */ smp_mb(); curr->task = NULL; wake_up_process(task); } mm->core_state = NULL; }
/* Ensure that nothing can wake it up, even SIGKILL */ static bool ptrace_freeze_traced(struct task_struct *task) { bool ret = false; spin_lock_irq(&task->sighand->siglock); if (task_is_traced(task) && !__fatal_signal_pending(task)) { task->state = __TASK_TRACED; ret = true; } spin_unlock_irq(&task->sighand->siglock); return ret; }
static void ptrace_unfreeze_traced(struct task_struct *task) { if (task->state != __TASK_TRACED) return; WARN_ON(!task->ptrace || task->parent != current); spin_lock_irq(&task->sighand->siglock); if (__fatal_signal_pending(task)) wake_up_state(task, __TASK_TRACED); else task->state = TASK_TRACED; spin_unlock_irq(&task->sighand->siglock); }
/* Ensure that nothing can wake it up, even SIGKILL */ static bool ptrace_freeze_traced(struct task_struct *task) { bool ret = false; /* Lockless, nobody but us can set this flag */ if (task->jobctl & JOBCTL_LISTENING) return ret; spin_lock_irq(&task->sighand->siglock); if (task_is_traced(task) && !__fatal_signal_pending(task)) { task->state = __TASK_TRACED; ret = true; } spin_unlock_irq(&task->sighand->siglock); return ret; }