diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index d4ccea599692..9c33163a6165 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1961,14 +1961,27 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) | |||
1961 | return; | 1961 | return; |
1962 | } | 1962 | } |
1963 | 1963 | ||
1964 | set_special_state(TASK_TRACED); | ||
1965 | |||
1964 | /* | 1966 | /* |
1965 | * We're committing to trapping. TRACED should be visible before | 1967 | * We're committing to trapping. TRACED should be visible before |
1966 | * TRAPPING is cleared; otherwise, the tracer might fail do_wait(). | 1968 | * TRAPPING is cleared; otherwise, the tracer might fail do_wait(). |
1967 | * Also, transition to TRACED and updates to ->jobctl should be | 1969 | * Also, transition to TRACED and updates to ->jobctl should be |
1968 | * atomic with respect to siglock and should be done after the arch | 1970 | * atomic with respect to siglock and should be done after the arch |
1969 | * hook as siglock is released and regrabbed across it. | 1971 | * hook as siglock is released and regrabbed across it. |
1972 | * | ||
1973 | * TRACER TRACEE | ||
1974 | * | ||
1975 | * ptrace_attach() | ||
1976 | * [L] wait_on_bit(JOBCTL_TRAPPING) [S] set_special_state(TRACED) | ||
1977 | * do_wait() | ||
1978 | * set_current_state() smp_wmb(); | ||
1979 | * ptrace_do_wait() | ||
1980 | * wait_task_stopped() | ||
1981 | * task_stopped_code() | ||
1982 | * [L] task_is_traced() [S] task_clear_jobctl_trapping(); | ||
1970 | */ | 1983 | */ |
1971 | set_current_state(TASK_TRACED); | 1984 | smp_wmb(); |
1972 | 1985 | ||
1973 | current->last_siginfo = info; | 1986 | current->last_siginfo = info; |
1974 | current->exit_code = exit_code; | 1987 | current->exit_code = exit_code; |
@@ -2176,7 +2189,7 @@ static bool do_signal_stop(int signr) | |||
2176 | if (task_participate_group_stop(current)) | 2189 | if (task_participate_group_stop(current)) |
2177 | notify = CLD_STOPPED; | 2190 | notify = CLD_STOPPED; |
2178 | 2191 | ||
2179 | __set_current_state(TASK_STOPPED); | 2192 | set_special_state(TASK_STOPPED); |
2180 | spin_unlock_irq(¤t->sighand->siglock); | 2193 | spin_unlock_irq(¤t->sighand->siglock); |
2181 | 2194 | ||
2182 | /* | 2195 | /* |