| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > Поиск resource leak (socket) |
| Автор: Zerstroer 12.11.2015, 19:45 | ||||||
| Здравствуйте, уважаемые! Достаточно давно и не спеша пишу приложение на "pure" C под Linux. Предварительная история болезни: Общий алгоритм работы такой: В бесконечном цикле: 1. через popen я вызываю внешний fping я пингую устройство, делаю pclose. 2. создаю сетевое соединение к устройству (через socket и connect), опрашиваю его, получаю данные, закрываю сетевое соединение (через close) 3. после чего через pipe и fork - передаю данные во внешнее приложение и получаю обратно от него результат так же через pipe. Все pipe старательно закрываю при завершении использования в каждом из потоков порожденном fork. И так далее по кругу в бесконечном цикле. В определенный момент через длительный период после запуска, при попытке создать pipe приложение падает с ошибкой "Too many open files". (получил из errno при создании pipe). Воспользовавшись вот http://oroboro.com/file-handle-leaks-server/ я получаю дамп открытых файловых дескрипторов на момент падения следующего вида:
Из чего следует, что, судя по всему, у меня длительное время не закрывались сокеты сетевого соединения. Но, сокеты я регулярно закрываю после использования и в случае ошибок с помощью close().
Подскажите, в какую сторону можно копать? С чем может быть связана эта ситуация? Дополнительная информация, которая может помочь. 1. Создаю я сокеты вот так:
2. У меня уже возникал http://forum.vingrad.ru/forum/topic-384476/anchor-entry2644213/0.html, связанный с тем, как методически верно следует идетифицировать закрытый сокет. 3. Я не использую setsockopt и SO_REUSEADDR - может ли быть ошибка связана с этим? |
| Автор: Zerstroer 13.11.2015, 09:13 |
| feodorv, отлично! Спасибо! Мне очень не хватало свежего взгляда. Своими глазами, я этот код уже замылил. Я так понял, что неоткрывшийся или ошибочно созданный сокет можно закрывать без проблем? Не вывалится ли errno = EBADF "The filedes argument is not a valid file descriptor." ? |
| Автор: xvr 13.11.2015, 14:42 | ||
Нельзя. Но у вас сокет создан вполне нормально. И то, что вы его не подсоединили куда то не отменяет необходимости его закрыть. |
| Автор: Zerstroer 13.11.2015, 17:22 | ||||||||
| xvr, у меня в createSocket() 3 "аварийных" выхода из функции создания сокета: 1.
2.
3.
Случаи №2 и №3 у меня никаких вопросов не вызывают, в них я действительно прошляпил закрытие сокета при аварийном случае. Мне не ясно с ситуацией №1 - должен ли я вызывать close(socket), если зафейлилось его создание? Что меня сбивает с панталыку: На википедии, есть https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D0%BA%D0%B5%D1%82%D1%8B_%D0%91%D0%B5%D1%80%D0%BA%D0%BB%D0%B8. В ней, в разделе "Высвобождение ресурсов" написано следующее:
Откуда у меня вопросы: А) В соответствии с путём исполнения когда socket() - выдал ошибку, должен ли я вызвать close()? Б) Сокеты Беркли и то, что мы здесь обсуждаем (Сокеты в Линукс) - это одно и то же? |
| Автор: feodorv 13.11.2015, 19:38 | ||||||||||||
А что именно Вы хотите закрывать в этом случае? Файловый дескриптор -1? Сокет не создан, соответственно, закрывать нечего. Ну, имелось в виду:
Скажите, если где-нибудь будет написано так:
|
| Автор: Zerstroer 13.11.2015, 23:12 |
| feodorv, спасибо за ответ. Я не хочу, что бы казалось, будто бы я оправдываюсь, но, я не стесняюсь задавать настолько глупые вопросы с очевидными ответами, после которых я глупо выгляжу. Формулировка в Википедии вносила малую толику сомнений, за которые я зацепился и задал этот вопрос. Я вообще, очень много сомневаюсь. Я понимаю, что вопрос глупый и я бесконечно благодарен Вам за время, потраченное на ответ. Спасибо. А форум мне всегда помогает, даже задавая здесь вопрос, зачастую, я при формулировке проблемы нахожу ответ. Продолжаю удивляться тому, что Винград продолжает в своём собственном ритме успешно функционировать... Вот такой сентиментальный оффтоп получился. По поводу задачи: Отправил на тестирование, по итогам либо задам возникшие вопросы, либо помечу тему как решенную. |
| Автор: feodorv 14.11.2015, 02:14 |
| Zerstroer, нет, я не хотел Вас задеть, просто вот прослеживается такая аналогия между socket() и fopen(), которую можно учесть при принятии решения. А в Интернете очень много чего пишут, много полезного, много неточного и бестолкового, к сожалению, не всегда есть возможность во всём этом разобраться. Задавайте вопросы, не стесняйтесь, форум для этого и создан |