Date: Fri, 15 Jul 2016 11:01:59 -0700 From: Mark Johnston <markj@FreeBSD.org> To: Konstantin Belousov <kostikbel@gmail.com> Cc: freebsd-current@FreeBSD.org Subject: Re: ptrace attach in multi-threaded processes Message-ID: <20160715180159.GA4487@wkstn-mjohnston.west.isilon.com> In-Reply-To: <20160715072720.GB38613@kib.kiev.ua> References: <20160712182414.GC71220@wkstn-mjohnston.west.isilon.com> <20160713033036.GR38613@kib.kiev.ua> <20160713040210.GA89573@wkstn-mjohnston.west.isilon.com> <20160713045439.GT38613@kib.kiev.ua> <20160713164247.GA2066@wkstn-mjohnston.west.isilon.com> <20160713191947.GW38613@kib.kiev.ua> <20160713200139.GC2066@wkstn-mjohnston.west.isilon.com> <20160714052537.GZ38613@kib.kiev.ua> <20160714181605.GA17310@wkstn-mjohnston.west.isilon.com> <20160715072720.GB38613@kib.kiev.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, Jul 15, 2016 at 10:27:20AM +0300, Konstantin Belousov wrote: > On Thu, Jul 14, 2016 at 11:16:05AM -0700, Mark Johnston wrote: > > Please see the program here: > > https://people.freebsd.org/~markj/ptrace_stop.c > > > > It cheats a bit: it uses SIGSTOP to stop the child before sending a > > SIGHUP to it. However, this is just for convenience; note that PT_ATTACH > > will result in a call to thread_unsuspend() on the child, so PT_ATTACH's > > SIGSTOP will be delivered to a running process. When ptrace attaches, > > the child stops and WSTOPSIG(status) == SIGHUP. When ptrace detaches, > > the child is left stopped. > No, it is not for convenience, it relies on another bug to get the effect, > see below. I see. I should have noted that the result can be reproduced without the first SIGSTOP, just not reliably. That is, I still occasionally get the following output when the kill(SIGSTOP) and subsequent waitpid() call are removed: stopping signal is 1 waiting on child... child is stopped after detach (sig 17) > > As I understand you intent, you prefer to get SIGSTOP from the first > waitpid(2) call after successful PT_ATTACH, am I right ? Hm, I don't care very much about that. I was just addressing your claim that the "debugger interface guarantees that SIGSTOP is noted." > At least for > single-threaded case, this can be achieved with a flag indicating that > we a doing first cursig(9) action after the attach, and preferring > SIGSTOP over any other queued signal. The new flag P2_PTRACE_FSTP > does just that. For mt case, I believe that some enchancements to > my proc_next_xthread() would fix that. This seems like a sound approach to me. It provides the guarantee I referenced above, and ensures that the SIGSTOP from PT_ATTACH is delivered before PT_DETACH. > > But when debugging the code, I found that it still does not work reliably > for your test. The reason is that issignal() consumes a queued stop signal > after the thread_suspend_switch(). It allows the attach to occur, but then > sigqueue_delete() calls ('take the signal!') eat the signal for attach. It > seems that we should consume stops before going to stop state. An open > question is how much this hurts when another (non-debugging) SIGSTOP is > queued while in stopped state. > > Please try this. Thanks, this seems to give the desired behaviour in the single-threaded case. I'll write a test case for the multi-threaded case next. Am I correct in thinking that r302179 could be reverted if your change is committed?
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20160715180159.GA4487>