3

Consider this program:

#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;
}

When I run this program by itself, resizing the terminal (thus generating SIGWINCH) doesn't do anything to it, and it keeps waiting for input on stdin. When I run it inside strace or ltrace, the SIGWINCH results in epoll_wait erroring with EINTR. My understanding of EINTR is that it's only generated if a signal calls a signal handler in your code, but I don't have any of them registered. I thought that strace or ltrace may have been setting one for me, so I tried explicitly setting it to SIG_IGN, but this still didn't stop the EINTR. Why is this happening?

3

They use ptrace(2), whose manual page comments

While being traced, the tracee will stop each time a signal is delivered, even if the signal is being ignored. (An exception is SIGKILL, which has its usual effect.) The tracer will be notified at its next call to waitpid(2) (or one of the related "wait" system calls); that call will return a status value containing information that indicates the cause of the stop in the tracee. While the tracee is stopped, the tracer can use various ptrace requests to inspect and modify the tracee. The tracer then causes the tracee to continue, optionally ignoring the delivered signal (or even delivering a different signal instead).

and later:

Note that a suppressed signal still causes system calls to return prematurely. In this case, system calls will be restarted: the tracer will observe the tracee to reexecute the interrupted system call (or restart_syscall(2) system call for a few system calls which use a different mechanism for restarting) if the tracer uses PTRACE_SYSCALL. Even system calls (such as poll(2)) which are not restartable after signal are restarted after signal is suppressed; however, kernel bugs exist which cause some system calls to fail with EINTR even though no observable signal is injected to the tracee.

By default, SIGWINCH is ignored, but it sounds as if epoll is similar enough to poll that the EINTR is visible to the caller (even with the restart).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.