Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Jun 2002 12:59:13 -0700 (PDT)
From:      Peter Edwards <pmedwards@eircom.net>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/39201: ptrace(2) and rfork(RFLINUXTHPN) confuse wait()
Message-ID:  <200206121959.g5CJxDw7042875@www.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         39201
>Category:       misc
>Synopsis:       ptrace(2) and rfork(RFLINUXTHPN) confuse wait()
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jun 12 13:00:09 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Peter Edwards
>Release:        4.6-RC
>Organization:
>Environment:
FreeBSD rocklobster 4.6-RC FreeBSD 4.6-RC #5: Wed Jun 12 20:34:22 IST 2002     petere@rocklobster:/a/archie/host/pub/FreeBSD/stable/src/sys/compile/ROCKLOBSTER  i386

>Description:
As reported on hackers@ and met with a hail if silence :-)

http://docs.freebsd.org/cgi/getmsg.cgi?fetch=80369+0+current/freebsd-hackers

kern_exit.c:wait1() has the following lines in -STABLE:
>  if ((p->p_sigparent != SIGCHLD) ^ ((uap->options & WLINUXCLONE)!= 0))
>          continue;

As it is, if you ptrace(PT_ATTACH) to a process started with
rfork(flags|RFLINUXTHPN), and do a waitpid() as you normally would, 
this causes waitpid() to fail with ECHILD, because the original
parent/child relationship doesn't hold, and the debugger doesn't
know that the debugee was started with RFLINUXTHPN. This can also
mean that the ptrace(PT_DETACH) ends up killing the process,
because you can't guarantee that it is stopped by the time you
get to do the ptrace(PT_DETACH). In order to allow existing
ptrace(2)-using programs to attach to such processes, would the
following be more appropriate?

> if ((p->p_sigparent != SIGCHILD && (p->p_flag & P_TRACED) == 0) ^
>     ((uap->options & WLINUXCLONE) != 0))

(BTW: Why "^" rather than "!=" ? I would have thought a boolean
operator more natural here.)

Cheers,
Peter.
>How-To-Repeat:
Try attaching to a process started with rfork(RFLINUXTHPN) with gdb.

>Fix:
This fixes it locally.

RCS file: /pub/FreeBSD/development/FreeBSD-CVS/src/sys/kern/kern_exit.c,v
retrieving revision 1.92.2.10
diff -u -r1.92.2.10 kern_exit.c
--- kern_exit.c 29 Apr 2002 09:42:35 -0000      1.92.2.10
+++ kern_exit.c 12 Jun 2002 19:27:23 -0000
@@ -438,7 +438,8 @@
                 * and the WLINUXCLONE option signifies we want to wait for threads
                 * and not processes.
                 */
-               if ((p->p_sigparent != SIGCHLD) ^ ((uap->options & WLINUXCLONE) != 0))
+               if ((p->p_sigparent != SIGCHLD && (p->p_flag & P_TRACED) == 0) ^
+                           ((uap->options & WLINUXCLONE) != 0))
                        continue;
 
                nfound++;


>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200206121959.g5CJxDw7042875>