Как предотвратить SIGPIPE или предотвратить завершение работы сервера?

Достаточно стандартная программа сервера TCP на C ++, использующая pthreads , bind , listen и accept ]. У меня есть сценарий, что сервер завершает работу (читай: сбой), когда я убиваю подключенного клиента.

Причина сбоя в том, что write () вызывает файл не работает, поэтому программа получает SIGPIPE. И я думаю, это приводит к выходу с сервера.

Я подумал: «Конечно, необработанный сигнал означает выход», поэтому давайте воспользуемся signal () :

signal(SIGPIPE, SIG_IGN);

потому что, взято из man 2 write :

EPIPE fd подключен к каналу или сокету, конец чтения которого закрыт. Когда это произойдет, процесс записи также получит сигнал SIGPIPE. (Таким образом, возвращаемое значение записи видно только в том случае, если программа улавливает, блокирует или игнорирует этот сигнал.)

Увы, нет. Ни в серверном, ни в клиентском потоках это, похоже, не помогает.

Итак, как мне запретить вызову write () поднять этот сигнал, или (чтобы быть прагматический), как остановить выход сервера.


Моя диагностика:

  • серверный поток запущен, привязка, прослушивание, прием.
  • позволить клиенту подключиться (например, через telnet)
  • отправить pkill telnet для сбоя клиента

нежелательное поведение: сервер завершает работу, в gdb с

... in write () at ../sysdeps/unix/syscall-template.S:82
82      T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)

и трассировкой :

#0  ... in write () at ../sysdeps/unix/syscall-template.S:82
#1  ... in ClientHandler::mesg(std::string) ()
#2  ... in ClientHandler::handle() ()
#3  ... in start_thread (arg=<value optimized out>) at pthread_create.c:300
#4  ... in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#5  ... in ?? ()
18
задан Jonathan Leffler 25 July 2011 в 21:01
поделиться