Warum führen strace und ltrace dazu, dass EINTR ausgeführt wird?

Warum führen strace und ltrace dazu, dass EINTR ausgeführt wird?

Betrachten Sie dieses Programm:

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

Wenn ich dieses Programm allein ausführe, hat die Größenänderung des Terminals (und damit die Generierung von SIGWINCH) keine Auswirkungen darauf und es wartet weiter auf Eingaben auf stdin. Wenn ich es innerhalb von strace oder ltrace ausführe, führt SIGWINCH zu einem epoll_wait-Fehler mit EINTR. Mein Verständnis von EINTR ist, dass es nur generiert wird, wenn ein Signal einen Signalhandler in Ihrem Code aufruft, aber ich habe keinen davon registriert. Ich dachte, dass strace oder ltrace vielleicht einen für mich gesetzt haben, also habe ich versucht, ihn explizit auf SIG_IGN zu setzen, aber das hat EINTR trotzdem nicht gestoppt. Warum passiert das?

Antwort1

Sie benutzenptrace(2), deren Manualpage-Kommentare

Während der Verfolgung wird der Verfolgte jedes Mal angehalten, wenn ein Signal gesendet wird.auch wenn das Signal ignoriert wird. (Eine Ausnahme ist SIGKILL, was seine übliche Wirkung hat.) Der Verfolger wird bei seinem nächsten Anruf benachrichtigt,waitpid(2)(oder einer der verwandten „wait“-Systemaufrufe); dieser Aufruf gibt einen Statuswert zurück, der Informationen enthält, die den Grund für den Stopp des verfolgten Prozesses angeben. Während der verfolgte Prozess gestoppt ist, kann der Tracer verschiedene Ptrace-Anfragen verwenden, um den verfolgten Prozess zu untersuchen und zu ändern. Der Tracer veranlasst dann, dass der verfolgte Prozess fortgesetzt wird, wobei er optional das übermittelte Signal ignoriert (oder stattdessen sogar ein anderes Signal übermittelt).

und später:

Beachten Sie, dass ein unterdrücktes Signal immer noch dazu führt, dass Systemaufrufe vorzeitig zurückkehren. In diesem Fall werden Systemaufrufe neu gestartet: Der Tracer beobachtet den Tracee, um den unterbrochenen Systemaufruf erneut auszuführen (oder restart_syscall(2) Systemaufruf für einige Systemaufrufe, die einen anderen Mechanismus zum Neustarten verwenden), wenn der Tracer PTRACE_SYSCALL. Sogar Systemaufrufe (wiepoll(2)), die nach dem Signal nicht neu gestartet werden können, werden nach der Unterdrückung des Signals neu gestartet;Es gibt jedoch Kernel-Bugs, die dazu führen, dass einige Systemaufrufe mit EINTR fehlschlagen, obwohl kein erkennbares Signal in den Tracee eingespeist wird..

Standardmäßig,SIGWINCHwird ignoriert, aber es hört sich so an, als ob epolles ähnlich genug ist poll, dass es EINTRfür den Anrufer sichtbar ist (auch beim Neustart).

verwandte Informationen