mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-24 07:31:41 +00:00
ptrace: relocate set_current_state(TASK_TRACED) in ptrace_stop()
In ptrace_stop(), after arch hook is done, the task state and jobctl bits are updated while holding siglock. The ordering requirement there is that TASK_TRACED is set before JOBCTL_TRAPPING is cleared to prevent ptracer waiting on TRAPPING doesn't end up waking up TRACED is actually set and sees TASK_RUNNING in wait(2). Move set_current_state(TASK_TRACED) to the top of the block and reorganize comments. This makes the ordering more obvious (TASK_TRACED before other updates) and helps future updates to group stop participation. This patch doesn't cause any functional change. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
This commit is contained in:
parent
755e276b33
commit
81be24b8cd
1 changed files with 13 additions and 15 deletions
|
@ -1732,6 +1732,18 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We're committing to trapping. TRACED should be visible before
|
||||||
|
* TRAPPING is cleared; otherwise, the tracer might fail do_wait().
|
||||||
|
* Also, transition to TRACED and updates to ->jobctl should be
|
||||||
|
* atomic with respect to siglock and should be done after the arch
|
||||||
|
* hook as siglock is released and regrabbed across it.
|
||||||
|
*/
|
||||||
|
set_current_state(TASK_TRACED);
|
||||||
|
|
||||||
|
current->last_siginfo = info;
|
||||||
|
current->exit_code = exit_code;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If @why is CLD_STOPPED, we're trapping to participate in a group
|
* If @why is CLD_STOPPED, we're trapping to participate in a group
|
||||||
* stop. Do the bookkeeping. Note that if SIGCONT was delievered
|
* stop. Do the bookkeeping. Note that if SIGCONT was delievered
|
||||||
|
@ -1742,21 +1754,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
|
||||||
if (why == CLD_STOPPED && (current->jobctl & JOBCTL_STOP_PENDING))
|
if (why == CLD_STOPPED && (current->jobctl & JOBCTL_STOP_PENDING))
|
||||||
gstop_done = task_participate_group_stop(current);
|
gstop_done = task_participate_group_stop(current);
|
||||||
|
|
||||||
current->last_siginfo = info;
|
/* entering a trap, clear TRAPPING */
|
||||||
current->exit_code = exit_code;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TRACED should be visible before TRAPPING is cleared; otherwise,
|
|
||||||
* the tracer might fail do_wait().
|
|
||||||
*/
|
|
||||||
set_current_state(TASK_TRACED);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We're committing to trapping. Clearing JOBCTL_TRAPPING and
|
|
||||||
* transition to TASK_TRACED should be atomic with respect to
|
|
||||||
* siglock. This should be done after the arch hook as siglock is
|
|
||||||
* released and regrabbed across it.
|
|
||||||
*/
|
|
||||||
task_clear_jobctl_trapping(current);
|
task_clear_jobctl_trapping(current);
|
||||||
|
|
||||||
spin_unlock_irq(¤t->sighand->siglock);
|
spin_unlock_irq(¤t->sighand->siglock);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue