We have a long standing bug in our production code. This is essentially a socket based daemon. It listens to a bunch of filedescriptors using select.
Occasionally (once a day or so), select will return with EBADF.
I have written code to search for the bad filedescriptor, that loops over each fd and calls select on it. These calls never return EBADF. I also tried fstat. They also never return EBADF.
I also rewrote the daemon to use poll. This did not help.
Does anyone have some other ideas ? (apart from i made a dumb mistake, which is all to easy to do with select).
If timeout is a NULL pointer, the select() call blocks until a socket becomes ready. To poll the sockets and return immediately, timeout should be a non-NULL pointer to a timeval structure with a value of 0.
If the timeout argument points to an object of type struct timeval whose members are 0, select() does not block. If the timeout argument is a null pointer, select() blocks until an event causes one of the masks to be returned with a valid (non-zero) value.
If the timeout happened, the select function will return 0 forever.
select() works by blocking until something happens on a file descriptor (aka a socket). What's 'something'? Data coming in or being able to write to a file descriptor -- you tell select() what you want to be woken up by.
I agree with James. With poll(), you have revents per fd which can easily be checked.
I.e.
struct pollfd fds[NUM_FDS];
int ret, i;
...
ret = poll(fds, NUM_FDS, POLL_TIMEOUT);
for (i = 0; i < NUM_FDS; i++)
if (fds[i].revents & POLLHUP || fds[i].revents & POLLNVAL)
... do something ...
Of course you would not implement it that way in the real world, its just an example. I stopped using select() a long time ago, poll() is a much better interface. You're correct, its just too easy to shoot yourself in the foot with select().
Most likely the select
is called on a closed file descriptor.
The usual source of that is reusing the fd_set
without re-initializing it.
Do you have anything going on in the signal handlers? (like re-opening a log file on a HUP?)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With