detach() logic

Dmitry V. Levin ldv at altlinux.org
Fri Jun 21 00:07:02 UTC 2013


On Thu, Jun 20, 2013 at 11:45:49AM +0200, Denys Vlasenko wrote:
> On 06/19/2013 04:35 PM, Dmitry V. Levin wrote:
> >>> PTRACE_DETACH should succeed and there should be no need to wait (and if
> >>> PTRACE_DETACH failed, then the tracee is no more so strace is expected
> >>> to wait for it).
> >>
> >> My point is, we *dont* wait if both DETACH and probing tkill(0)
> >> fail with ESRCH. This might be wrong in some situations.
> > 
> > I suppose in that case, if TCB_STRACE_CHILD bit is set, strace should
> > waitpid the tracee, expecting ECHILD or WIFSIGNALED status.
> 
> Ok, looks like *those* my fears were unfounded. At worst, we leak
> (don't wait for) a zombie when "strace PROG" form is ^C-ed:
> we detach() PROG, but not wait for it; but we exit immediately too.
> So the zombie is reparented to init and init cleans it up.
> 
> If we detach() in "strace -p PID" situation, we don't,
> and *shouldn't* eat exit status. I need to add a comment about it...

strace traces at most one child process; if there is such tracee, it has
TCB_STRACE_CHILD bit set.  This means one leaked zombie in the worst case.
If this leak happens at strace exit (detach called by cleanup), the zombie
will be reparented to init so there is no need to bother.  Another case
when detach can be called is '-b execve', and there is a very unlikely
chance for the strace's only child tracee to get killed while in
PTRACE_EVENT_EXEC stop.  In the latter case, the zombie will be leaked,
but I wouldn't bother much about it.

> However, now I see another, very simple bug in detach():
> 
>                 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
>                 error = ptrace(PTRACE_DETACH, tcp->pid, 0, 0);
> 
> What if sigstop_expected == 1 (IOW: TCB_IGNORE_ONE_SIGSTOP is set)?
> 
> We will DETACH _before_ we eat and discard SIGSTOP.
> After DETACH, we will do waitpid loop, see SIGSTOP,
> and... try DETACH again! lol :(

No, in that case waitpid will fail with ECHILD, so there would be no try
for the second PTRACE_DETACH.  With your recent commit v4.8-16-gfdfa47a,
strace will complain:
strace: detach: waitpid(12345): No child processes

I've actually managed to reproduce this warning with a very artificial test.

> Does it look like a real bug to you too?

It looks like a bug, SIGSTOP is certainly not expected after successful
PTRACE_DETACH.


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20130621/172446fd/attachment.bin>


More information about the Strace-devel mailing list