Messages in this thread | | | Date | Mon, 9 Nov 2015 19:55:06 +0100 | From | Oleg Nesterov <> | Subject | Re: ptrace() hangs on attempt to seize/attach stopped & frozen task |
| |
Hi,
On 11/09, Andrey Ryabinin wrote: > > Hi, > > So, the ptrace() hangs if we try to attach to stopped task from freezing cgroup. > It seems this was introduced by 5d8f72b55c2756("freezer: change ptrace_stop/do_signal_stop to use freezable_schedule()").
quite possible...
> See below for the exact scenario and small script to reproduce this. > > > Tracee: Tracer: > static bool do_signal_stop(int signr) > __set_current_state(TASK_STOPPED); > freezable_schedule(); > freezer_do_not_count(); > schedule(); /* waiting for wake up */ > > ptrace_attach() > if (task_is_stopped(task) && > task_set_jobctl_pending(task, JOBCTL_TRAP_STOP | JOBCTL_TRAPPING)) > signal_wake_up_state(task, __TASK_STOPPED); > > /* woken up by ptrace_attach() */ > freezer_count(); > __refrigerator() > /* And here we will hang, because tracee is now frozen in __refrigerator() */ > wait_on_bit(&task->jobctl, JOBCTL_TRAPPING_BIT, > TASK_UNINTERRUPTIBLE);
Thanks. All I can say I never liked this wait_on_bit() ;)
I need to think, but *at first glance* we can move this wait-for-stopped- traced-transition into do_wait() path, and this way clear_jobctl_trapping() can use __wake_up_parent(). Perhaps we just need to modify task_stopped_code() to take JOBCTL_TRAPPING into account...
Sure, debugger will block in sys_wait() after PTRACE_ATTACH/SEIZE. But this does not really differ from the case when the tracee was already frozen; SIGSTOP sent by ATTACH or PTRACE_INTERRUPT, so debugger will equally block in do_wait() until the tracee is unfrozen.
Oleg.
| |