From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751985AbbKIPMc (ORCPT ); Mon, 9 Nov 2015 10:12:32 -0500 Received: from mx2.parallels.com ([199.115.105.18]:47894 "EHLO mx2.parallels.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750997AbbKIPM3 (ORCPT ); Mon, 9 Nov 2015 10:12:29 -0500 From: Andrey Ryabinin Subject: ptrace() hangs on attempt to seize/attach stopped & frozen task To: Oleg Nesterov CC: Roland McGrath , Tejun Heo , LKML Message-ID: <5640B7F2.70406@virtuozzo.com> Date: Mon, 9 Nov 2015 18:12:50 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-ClientProxiedBy: US-EXCH.sw.swsoft.com (10.255.249.47) To US-EXCH2.sw.swsoft.com (10.255.249.46) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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()"). 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); Reproduecer: ----------- #!/bin/bash sleep 100 & pid=$! kill -SIGSTOP $pid mkdir -p /sys/fs/cgroup/freezer/test echo $pid > /sys/fs/cgroup/freezer/test/tasks echo FROZEN > /sys/fs/cgroup/freezer/test/freezer.state echo '#include #include int main(int argc, char **argv) { int pid = atoi(argv[1]); return ptrace(PTRACE_SEIZE, pid, NULL, 0); } ' | gcc -x c - ./a.out $pid