From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758329AbcIMV6j (ORCPT ); Tue, 13 Sep 2016 17:58:39 -0400 Received: from mail-yw0-f175.google.com ([209.85.161.175]:34974 "EHLO mail-yw0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754521AbcIMV6i (ORCPT ); Tue, 13 Sep 2016 17:58:38 -0400 MIME-Version: 1.0 In-Reply-To: <20160823153428.GB4067@redhat.com> References: <20160818143750.GA24070@redhat.com> <20160818153806.GA25492@redhat.com> <20160818162311.GA27883@redhat.com> <20160823153428.GB4067@redhat.com> From: Keno Fischer Date: Tue, 13 Sep 2016 17:57:56 -0400 Message-ID: Subject: Re: ptrace group stop signal number not reset before PTRACE_INTERRUPT is delivered? To: Oleg Nesterov Cc: Roland McGrath , linux-kernel@vger.kernel.org, Tejun Heo Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Oleg, I have another obscure ptrace question which seems somewhat related, so let me ask it here. Consider this: ``` static int sigchld_counter = 0; void sigchld_handler(int sig) { (void)sig; sigchld_counter++; } int main(void) { signal(SIGCHLD, sigchld_handler); pid_t child; if (0 == (child = fork())) { raise(SIGSTOP); assert(0); // Should never be continued } // Wait until stopped int status; pid_t wret = waitpid(child, &status, __WALL | WSTOPPED); assert(wret == child); assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP); assert(sigchld_counter == 1); // Now PTRACE_SEIZE the child long err = ptrace(PTRACE_SEIZE, child, NULL, (void*)PTRACE_O_TRACESYSGOOD); assert(err == 0); // Make sure that didn't cause a notification wret = waitpid(child, &status, __WALL | WSTOPPED | WNOHANG); assert(wret == 0); assert(sigchld_counter == 1); } ``` I wouldn't have expected the PTRACE_SEIZE to generate another SIGCHLD/be waitable again, (the last two assertions fail). Is that supposed to happen? If so, I'd like to update the man page to mention this behavior, but I wanted to check with you first. Thanks, Keno On Tue, Aug 23, 2016 at 11:34 AM, Oleg Nesterov wrote: > On 08/18, Keno Fischer wrote: >> >> On Thu, Aug 18, 2016 at 12:23 PM, Oleg Nesterov wrote: >> > >> > And you if you get PTRACE_EVENT_STOP and WSTOPSIG() == SIGTTIN after >> > PTRACE_INTERRUPT, you know that the tracee did not report the "new" >> > SIGTTIN. >> >> It seems possible to remember whether or not we injected a stopping >> signal and if so the next PTRACE_EVENT_STOP is a group-stop, otherwise >> a PTRACE_INTERRUPT stop. Currently what I do is the other way around, >> after issuing PTRACE_INTERRUPT, the first (if any) of the next two >> stops that is a PTRACE_EVENT_STOP get interpreted as a >> PTRACE_INTERRUPT stop. I haven't thought through this fully yet, so I >> can't give you a concrete example I worried about, it just seems >> fragile compared to just checking whether WSTOPSIG() == SIGTRAP. > > Yes, I see your point. And to remind, I was confused too. > > Perhaps we can add another THIS_SIGNAL_WAS_ALREADY_REPORTED bit, but > you know, I'd prefer to avoid another subtle change in behaviour. You > can never know if it is "safe" or not when it comes to ptrace, perhaps > some application already relies on this WSTOPSIG(). > > Oleg. >