Fix forkfd on OS X 10.7 and earlier

dtruss logs show that the signal handler does enter and is active, since
it does the first waitid() call, but then returns immediately:

 waitid(0x0, 0x0, 0x7FFF62D7C468)               = 0 0
 sigreturn(0x7FFF62D7C9A0, 0x1E, 0x0)           = 0 Err#-2

Since there was no error return, we conclude that si_pid was zero on
return. Source code for OS X 10.7 confirms that si_pid is set to zero
unconditionally, which is rather stupid:
 http://fxr.watson.org/fxr/source/bsd/kern/kern_exit.c?v=xnu-1699.24.8#L1330

This is fixed for OS X 10.8:
 http://fxr.watson.org/fxr/source/bsd/kern/kern_exit.c?v=xnu-2050.18.24#L1399

Without that information, we have to scan each child anyway, so
just disable the waitid() solution on OS X. This is a "hammer" solution
which will get forkfd working. We can later try and detect at runtime
whether waitid() is working.

Change-Id: Ic5d393bfd36e48a193fcffff13bb584927cdeafe
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
This commit is contained in:
Thiago Macieira 2015-01-20 23:59:38 -08:00
parent bd1be70e0e
commit 9931fa9df4

View File

@ -58,7 +58,18 @@
# include <sys/eventfd.h> # include <sys/eventfd.h>
#endif #endif
#if _POSIX_VERSION-0 >= 200809L || _XOPEN_VERSION-0 >= 500 #if defined(__APPLE__)
/* Up until OS X 10.7, waitid(P_ALL, ...) will return success, but will not
* fill in the details of the dead child. That means waitid is not useful to us.
* Therefore, we only enable waitid() support if we're targetting OS X 10.8 or
* later.
*/
# include <Availability.h>
# include <AvailabilityMacros.h>
# if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
# define HAVE_WAITID 1
# endif
#elif _POSIX_VERSION-0 >= 200809L || _XOPEN_VERSION-0 >= 500
# define HAVE_WAITID 1 # define HAVE_WAITID 1
#endif #endif