Выберите EBADF: какой FD плох? - PullRequest
12 голосов
/ 19 мая 2009

У нас есть давняя ошибка в нашем производственном коде. По сути это демон на основе сокетов. Он слушает кучу файловых дескрипторов, используя select.

Иногда (один раз в день или около того) выбор возвращается с EBADF.

Я написал код для поиска плохого файлового дескриптора, который зацикливается на каждом fd и вызывает select для него. Эти звонки никогда не возвращают EBADF. Я тоже пробовал fstat. Они также никогда не возвращают EBADF.

Я также переписал демон, чтобы использовать опрос. Это не помогло.

У кого-нибудь есть другие идеи? (кроме того, что я сделал глупую ошибку, которую легко сделать с помощью select).

Ответы [ 3 ]

4 голосов
/ 20 мая 2009

Я согласен с Джеймсом. С помощью poll () у вас есть реванши на fd, которые легко проверить.

* 1003 Т.е. *

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 ...

Конечно, вы бы не реализовали это таким образом в реальном мире, это всего лишь пример. Я давно перестал использовать select (), poll () - намного лучший интерфейс. Вы правы, слишком просто выстрелить себе в ногу с помощью select ().

4 голосов
/ 19 мая 2009

Скорее всего, select вызывается по закрытому файловому дескриптору. Обычный источник этого - повторное использование fd_set без его повторной инициализации. У вас что-нибудь происходит в обработчиках сигналов? (например, повторно открыть файл журнала на HUP?)

3 голосов
/ 19 мая 2009

Если вы используете poll (), вы можете просмотреть данные и определить, какая из них не работает, что является большим преимуществом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...