Hi! Ping.
On Wed, 14 Nov 2012 15:53:53 +0100, I wrote: > On Thu, 08 Sep 2011 12:40:30 +0200, Thomas Schwinge <tho...@schwinge.name> > wrote: > > This is about fork in glibc. It's leaking port rights. > > (We're not leaking port rights, but we're »handling user reference counts > incorrectly«, as I corrected myself later on.) > > > Roland, thanks for the good source code commentation, which is mostly > > up-to-date; this has helped a lot for understanding! > > > > > > On Mon, 22 Nov 2010 11:56:45 +0100, Samuel Thibault > > <samuel.thiba...@gnu.org> wrote: > > > Thomas Schwinge, le Mon 22 Nov 2010 09:38:24 +0100, a écrit : > > > > 463 (err = __mach_port_mod_refs (newtask, ss->thread, > > > > 464 MACH_PORT_RIGHT_SEND, > > > > 465 thread_refs))) > > > > > > and > > > > > > thread_refs = 65534 > > > > > > it happens that gnumach has > > > > > > #define MACH_PORT_UREFS_MAX ((mach_port_urefs_t) ((1 << 16) - 1)) > > > > > > So the original issues seems to be that thread_refs went in the sky. > > > > Indeed there are port leaks in this code. In the *parent*, mind you. > > And what happens is that after enough fork invocations, in the parent, > > the mach_thread_self (ss->thread above) user reference count will be > > 65534, and then the mach_port_mod_refs for newtask must fail, as it > > already has got one right, but can't add another 65534 due to > > MACH_PORT_UREFS_MAX. > > > > If you now consider that this bug was triggered by DejaGnu's runtest, > > which ``endlessly'' invokes GCC and other stuff on thousands of C test > > files in the GCC testsuite, this does make sense. The parent runtest > > process is invoking fork all the time, so the leak(s) just add up in the > > parent. > > Here is a patch. OK to commit? > > * sysdeps/mach/hurd/fork.c (__fork): Install correct number of > send rights for its main user thread in NEWTASK. > > diff --git sysdeps/mach/hurd/fork.c sysdeps/mach/hurd/fork.c > index 644838c..0e29f0f 100644 > --- sysdeps/mach/hurd/fork.c > +++ sysdeps/mach/hurd/fork.c > @@ -454,14 +453,10 @@ __fork (void) > (err = __mach_port_insert_right (newtask, ss->thread, > thread, MACH_MSG_TYPE_COPY_SEND))) > LOSE; > - /* We have one extra user reference created at the beginning of this > - function, accounted for by mach_port_names (and which will thus be > - accounted for in the child below). This extra right gets consumed > - in the child by the store into _hurd_sigthread in the child fork. */ > if (thread_refs > 1 && > (err = __mach_port_mod_refs (newtask, ss->thread, > MACH_PORT_RIGHT_SEND, > - thread_refs))) > + thread_refs - 1))) > LOSE; > if ((_hurd_msgport_thread != MACH_PORT_NULL) /* Let user have none. */ > && ((err = __mach_port_deallocate (newtask, _hurd_msgport_thread)) || Grüße, Thomas
pgpah2P4vNBLw.pgp
Description: PGP signature