Re: Crash with FD_SET when there are more than 1024 open files
Re: Crash with FD_SET when there are more than 1024 open files
- Subject: Re: Crash with FD_SET when there are more than 1024 open files
- From: Terry Lambert <email@hidden>
- Date: Thu, 15 Apr 2010 13:51:25 -0700
On Apr 15, 2010, at 8:54 AM, Stefan Haller wrote:
We are investigating a reproducible crash that happens in Bonjour code
when we have many files open. The crash happens in
DNSServiceProcessResult (part of mDNSResponder), which contains the
following code:
static int more_bytes(dnssd_sock_t sd)
{
struct timeval tv = { 0, 0 };
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(sd, &readfds);
return(select(sd+1, &readfds, (fd_set*)NULL, (fd_set*)NULL, &tv)
> 0);
}
Are you recompiling this code yourself? If so, here's the trivial fix
for this:
/*do this before #include <sys/select.h> */
#define _DARWIN_UNLIMITED_SELECT
...
static int more_bytes(dnssd_sock_t sd)
{
struct timeval tv = { 0, 0 };
int my_fdset[1 + sd / (8 * sizeof(int))]; /* c99 magic auto size
arrays */
fd_set *readfdsp = (void *)&my_fdset[0]; /* convert array to pointer
to struct containing bit vector */
FD_ZERO(readfdsp);
FD_SET(sd, readfdsp);
return(select(sd+1, readfdsp, (fd_set*)NULL, (fd_set*)NULL, &tv) > 0);
}
The select nfds parameter is limited in the procedural implementation
of select() itself, but that limit is a problem with the POSIX
assumptions about internal implementation details of the system call
limiting the copyin size to a stack declared fd_set internally, rather
than an allocated data area. It's more or less a bogus limitation on
select by POSIX, and is only enforced in user space in Libc.
Obviously, the FD_* macros don't enforce this limitation -- and would
have a hard time doing so, without potentially reevaluating their
arguments, which may have side effects, and which is prohibited (also
by POSIX; there's a specific negative assertion test in the validation
suite), so there's no way to keep you from shooting yourself in the
foot.
All that said, there is no existing Apple software which uses the
DNSServiceProcessResult() function, so it's likely that you could do
whatever you are doing which requires using that function a bit
differently, and avoid the problem entirely while at the same time
getting better structured code out of the deal.
-- Terry
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden