strace와 ltrace로 인해 EINTR이 발생하는 이유는 무엇입니까?

strace와 ltrace로 인해 EINTR이 발생하는 이유는 무엇입니까?

다음 프로그램을 고려해보세요:

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

이 프로그램을 단독으로 실행하면 터미널 크기를 조정하여(따라서 SIGWINCH 생성) 아무런 작업도 수행하지 않으며 stdin에서 입력을 계속 기다립니다. strace 또는 ltrace 내에서 실행하면 SIGWINCH로 인해 EINTR과 함께 epoll_wait 오류가 발생합니다. EINTR에 대한 나의 이해는 신호가 코드에서 신호 처리기를 호출하는 경우에만 생성되지만 등록된 신호가 없다는 것입니다. 나는 strace 또는 ltrace가 나를 위해 하나를 설정했을 수도 있다고 생각하여 명시적으로 SIG_IGN으로 설정하려고 시도했지만 여전히 EINTR을 중지하지 못했습니다. 왜 이런 일이 발생합니까?

답변1

그들은 사용한다ptrace(2), 매뉴얼 페이지에 주석이 있음

추적되는 동안 피추적자는 신호가 전달될 때마다 중지됩니다.신호가 무시되더라도. (예외는 SIGKILL, 이는 일반적인 효과를 갖습니다.) 추적 프로그램은 다음에 호출할 때 알림을 받습니다.waitpid(2)(또는 관련된 "대기" 시스템 호출 중 하나); 해당 호출은 피추적자의 중지 원인을 나타내는 정보가 포함된 상태 값을 반환합니다. 피추적자가 중지된 동안 추적자는 다양한 ptrace 요청을 사용하여 피추적자를 검사하고 수정할 수 있습니다. 그런 다음 추적자는 피추적자가 계속하도록 하고 선택적으로 전달된 신호를 무시합니다(또는 대신 다른 신호를 전달하기도 함).

그리고 나중에:

억제된 신호로 인해 시스템 호출이 조기에 반환된다는 점에 유의하세요. 이 경우 시스템 호출이 다시 시작됩니다. 추적자는 중단된 시스템 호출을 재실행하기 위해 피추적자를 관찰합니다(또는 restart_syscall(2) 다시 시작하기 위해 다른 메커니즘을 사용하는 몇 가지 시스템 호출에 대한 시스템 호출) 추적 프로그램이 사용하는 경우 PTRACE_SYSCALL. 시스템 호출(예:poll(2)) 신호가 억제된 후 신호가 다시 시작된 후에는 다시 시작할 수 없습니다.그러나 관찰 가능한 신호가 피추적자에게 주입되지 않았음에도 불구하고 EINTR과 함께 일부 시스템 호출이 실패하게 만드는 커널 버그가 존재합니다..

기본적으로,SIGWINCH무시되지만 호출자에게 표시될 만큼 epoll비슷한 것처럼 들립니다(다시 시작하더라도).pollEINTR

관련 정보