Совершенно стандартная программа на C ++ TCP-сервере, использующая 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 ?? ()