Hi! This is about fork in glibc. It's leaking port rights.
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. One patch for the TLS code is below; Samuel please have a look. (Thou shalt not invoke mach_thread_self needlessly -- or is there a reason?) Unfortunately, this is not all. I'm continuing. One bit of wisdom: thou shalt not look at the user reference count of mach_task_self, mach_thread_self, mach_host_self for it is of no relevance. (See the GNU Mach reference manual.) But it may be harmful, as seen above. If we conclude that is true, then why invoke mach_port_mod_refs at all for these three? That's what I'm looking at next. --- /media/kepler-data/home/thomas/tmp/source/glibc/tschwinge/Roger_Whittaker/sysdeps/mach/hurd/fork.c 2011-09-08 12:35:54.000000000 +0200 +++ sysdeps/mach/hurd/fork.c 2011-09-08 01:15:13.000000000 +0200 @@ -538,7 +538,7 @@ _hurd_longjmp_thread_state (&state, env, 1); /* Do special thread setup for TLS if needed. */ - if (err = _hurd_tls_fork (thread, __mach_thread_self (), &state)) + if (err = _hurd_tls_fork (thread, ss->thread, &state)) LOSE; if (err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR, Grüße, Thomas
pgpcPiZfiR5z8.pgp
Description: PGP signature