Пару рабочих дней убил на отлов элементарной ошибки.
Выглядело все следующим образом:
* имелся некий TCP сервер с уже кучей кода и модулей, но в принципе рабочий;
* еще один тот же TCP сервер, но на другой машине (плате);
* первый TCP сервер подключался к другому, как клиент с целью обмена данными.
Ошибка была в том, что соединение по какой-то причине отрабатывалось неверно и повисало в состоянии CLOSE_WAIT. Первый сервер распознавал это как неактивный сервер и дисконнектил его по таймауту, второй - не видел соединения вообще.
Соответственно, ключевым словом для гугления стало состояние CLOSE_WAIT, на которое вываливается куча нетривиальной инфы, которую замучились перепроверять. Но вроде как оказалось, что все критерии выполнены и ошибок быть не должно.
Далее, начали проверять отработку процесса подключения ко второму серверу. Подключение детектировалось по наличию данных в сокете путем проверки select()-ом. Сервер был однопоточный и проверки запускались периодически + выполнялась служебная работа. Select() измучили как только можно, перепроверяя отдаваемые ему параметры по десять раз и все равно CLOSE_WAIT оставлись. Что сразу смущало - они были _не всегда_.
Когда уже наступила фаза отчаяния, случайно добавленная отладка в планировщик вызовов select() выявила, что планировщик тупо переставал запускаться. Оказывается дело было в том, что планировщик запускался по таймауту, который вычислялся последовательными вызовами gettimeofday(). А на той плате была особенность - она корректировала свое системное время. На несколько месяцев. А проверки на такие таймауты не было. Занавес.
Как можно силой мысли доползти от диагностики в виде CLOSE_WAIT на сокете до неверной отработки таймаутов планировщика я не знаю. :(
Pipewire 1.6.0
месяц назад
