LINUX.ORG.RU

Почему приложение может тихо завершаться в функции «send()»?


0

1

Имеется ввиду ssize_t send(int s, const void *buf, size_t len, int flags);, которая с сокетами работает.

Какие могут быть варианты? Да, возможно закрывается соединение к тому моменту, как я отправляю (сокеты-асинхронные), но тогда бы приходил SIGPIPE. А тут просто завершается без всяких новостей. Буффер точно исправен, размер точно тот. Всё утыкано std::cout, вижу, что параметры корректные.

Приложение - http-сервер, обрабатывает, наверное 1000 запросов, используя для каждого send(), но в какой-то момент send становится последним.

Что проверено: - память не течёт - указатель на буффер - ОК, размер какой нужно. - сокет - ну точно созданный или accept-нутый, и точно не -1. - сигнал SIGPIPE не приходит.

Не спрашивайте, правильно ли я всё проверил, просто выдайте варианты падения на send или сомнения в моих проверках. Доказывать то, что я проверил всё хорошо, не буду, но заострю внимание и проверю ещё раз что-то конкретно, если будут советы.

Исходники не покажу - незачем, просто вспомните варианты, когда send может завалить приложение, я уже не знаю, что проверять )

Спасибо!

попробуй atexit, может там по стеку будет видно что дергается _exit например, тогда поставишь там брекпоинт

anonymous
()

> когда send может завалить приложение, я уже не знаю, что проверять )

приложение может валится в самом неожиданном месте если упахивается память. Может быть выход за границу массива, запись по неверной ссылке, практически что угодно как до момента вызова функции, так и во время оного, например в другой нити или обработчике сигнала.

Диагностируется сборкой с другом окружении (с другими библиотеками, под другую архитектуру), добавлением искуственых задержек, пустых буферов, выделением лишней памяти, изменением числа нитей и тому подобным - на тестовых наборах программа будет валиться подругому (в других местах) или перестанет валиться вовсе.

Лечиться аккуратной борьбой со всеми предупреждениями компилятора, затем линтера (http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis) затем valgrind`ом её :) если это не помогает, то в руки отладчик и внимательно мониторить основные данные - очереди, дескрипторы, особенно лежащие рядом с использованными в злосчастном send.

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

Я ж написал - валится на send(). Один поток, вокруг сенд натыкано std::cout + std::cout.flush(), так что видно, что валится всё на send().

mriadus
() автор топика
Ответ на: комментарий от anonymous

Мне ничего не даст знание о том, что дёргается _exit(). Ну дёргается и что? И так вижу, что что-то такое явно дёргается )))

mriadus
() автор топика

>Какие могут быть варианты?

SIGPIPE (запись в сокет после того, как принимающая сторона его закрыла)

#include <signal.h>
#include <errno.h>
#include <stdlib.h>
...
        struct sigaction sa;
        sa.sa_handler = SIG_IGN;
        sa.sa_flags = 0;
        if (sigemptyset(&sa.sa_mask) == -1 || sigaction(SIGPIPE, &sa, 0) == -1) {
            perror("failed to ignore SIGPIPE; sigaction");
            exit(EXIT_FAILURE);
        }
...
linuxfan
()
Ответ на: комментарий от mriadus

> валится на send(). Один поток, вокруг сенд натыкано std::cout + std::cout.flush(), так что видно, что валится всё на send().

недавно был тред (http://www.linux.org.ru/forum/development/5401985), в котором у автора всё валилось на rand() :)

MKuznetsov ★★★★★
()

Эм, а корку снять не пробовал?

1) перед запуском ulimit -c unlimited

2) Проверить, что в /proc/sys/kernel/core_pattern нету никаких пайпов и devnull'ов

3) echo «8 4 1 8» > /proc/sys/kernel/printk

мониторим dmesg и ловим корку

еще можно его под strace'ом запустить и посмотреть, когда и как оно отвалилось. сигналы полученные тоже будут видны

DELIRIUM ☆☆☆☆☆
()

запусти под gdb или strace, покажет, если прийдет какой импульс убиться извне.

P.S. И собери-ка с --save-temps, посмотри развернутый после препроцессора сорец (*.i) - там send останется? может какая злая либа сделала #define send send_с_кучей_тихих_ассертов и забыла сделать в конце #undef send ? Я однажды видел где-то в системных либах от apple феерический глобальный макрос #define max(a,b) ...

hydraulicbrakefluid
()
Ответ на: комментарий от hydraulicbrakefluid

max в c std lib, ЕМНИП, часто как макрос и реализуется.

По сабжу, из-за ошибки(ок) в программе и/или библиотеках. С теми данными, которые Вы дали, большего не скажешь.

Приложение - http-сервер, обрабатывает, наверное 1000 запросов, используя для каждого send(), но в какой-то момент send становится последним.

Т.е. систематичности Вы не видите?

Удостоверьтесь, что не приходит SIGSEGV или SIGPIPE, повесив обработчик.

hunt
()
Ответ на: комментарий от hunt

> Удостоверьтесь, что не приходит SIGSEGV или SIGPIPE, повесив обработчик.

проще strace'ом. Еще может прийти SIGKILL от ядра при исчерпании, например памяти, в стрейсе это тоже будет видно. В таком случае ядро об этом сообщит в dmesg, поэтому я выше советовал поднять уровень printk, и смотреть его.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от hunt

> max в c std lib, ЕМНИП, часто как макрос и реализуется.

Нет, не реализует. В С-шной stdlib есть например fmax для float-ов, но нет и быть не может макроса с именем «max», тот, кто пишет «#define max(a,b)...» в подключаемом много-где *.h файле достоен быть битым ногами

max и min есть в плюсовом std::, реализованы безопасно через теплейты.

hydraulicbrakefluid
()
Ответ на: комментарий от hydraulicbrakefluid

Да, погнал. Действительно подло делать в стороннем хедере такой макрос. =)

И про strace тоже согласен.

hunt
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.