¿Por qué strace y ltrace hacen que ocurra EINTR?

¿Por qué strace y ltrace hacen que ocurra EINTR?

Considere este programa:

#include <stdio.h>
#include <sys/epoll.h>

int main(void) {
       int epfd = epoll_create1(0);
       struct epoll_event event;
       event.events = EPOLLIN;
       event.data.fd = 0;
       epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &event);
       epoll_wait(epfd, &event, 1, -1);
       perror("epoll_wait");
       return 0;
}

Cuando ejecuto este programa por sí solo, cambiar el tamaño del terminal (generando así SIGWINCH) no le hace nada y sigue esperando entradas en la entrada estándar. Cuando lo ejecuto dentro de strace o ltrace, SIGWINCH genera un error epoll_wait con EINTR. Según tengo entendido, EINTR solo se genera si una señal llama a un controlador de señales en su código, pero no tengo ninguno registrado. Pensé que strace o ltrace podrían haber estado configurando uno para mí, así que intenté configurarlo explícitamente en SIG_IGN, pero esto aún no detuvo el EINTR. ¿Por qué está pasando esto?

Respuesta1

Ellos usanptrace(2), cuya página de manual comenta

Mientras se rastrea, el rastreador se detendrá cada vez que se entregue una señal,incluso si la señal está siendo ignorada. (Una excepción es SIGKILL, que tiene su efecto habitual). El rastreador será notificado en su próxima llamada awaitpid(2)(o una de las llamadas al sistema de "espera" relacionadas); esa llamada devolverá un valor de estado que contiene información que indica la causa de la detención en el rastreado. Mientras el rastreador está detenido, el rastreador puede utilizar varias solicitudes de ptrace para inspeccionar y modificar el rastreador. Luego, el rastreador hace que el rastreado continúe, ignorando opcionalmente la señal entregada (o incluso entregando una señal diferente).

y después:

Tenga en cuenta que una señal suprimida todavía hace que las llamadas al sistema regresen prematuramente. En este caso, las llamadas al sistema se reiniciarán: el rastreador observará al rastreado para volver a ejecutar la llamada al sistema interrumpida (o restart_syscall(2) llamada al sistema para algunas llamadas al sistema que usan un mecanismo diferente para reiniciar) si el rastreador usa PTRACE_SYSCALL. Incluso las llamadas al sistema (comopoll(2)) que no se pueden reiniciar después de que la señal se reinicie después de que se suprima la señal;sin embargo, existen errores en el kernel que hacen que algunas llamadas al sistema fallen con EINTR incluso aunque no se inyecte ninguna señal observable al rastreado..

Por defecto,SIGWINCHse ignora, pero suena como si epollfuera lo suficientemente similar como pollpara que EINTRsea visible para la persona que llama (incluso con el reinicio).

información relacionada