
次のプログラムを検討してください。
#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が生成される)、何も起こらず、引き続き標準入力への入力を待ちます。 strace または ltrace で実行すると、SIGWINCH は epoll_wait で EINTR エラーを発生させます。 EINTRの私の理解は、シグナルがコードからシグナルハンドラを呼び出すときにのみ生成されますが、それらのどれも登録しないことです。私はstraceやltraceが私のために1つを設定したかもしれないと思い、明示的にSIG_IGNに設定しようとしましたが、まだEINTRをブロックできませんでした。なぜこれが起こるのですか?
答え1
彼らは使うptrace(2)
、彼のマニュアルページがコメントしました。
追跡されている間、追跡されている人は信号が与えられるたびに停止します。信号を無視しても。 (一つの例外は
SIGKILL
、これは一般的な効果があります。 )トラッカーは、次回呼び出されたときに通知を受け取ります。waitpid(2)
(または関連する「待機」システムコールの1つ)この呼び出しは、追跡された人が停止した理由を示す情報を含むステータス値を返します。被追跡者が停止すると、トラッカーは様々な ptrace 要求を使用して被追跡者を検査および修正できます。その後、トラッカーは追跡が進行するようにアクティブにし、選択的に転送された信号を無視します(または他の信号転送も可能です)。
それから:
シグナルを抑制すると、システムコールが早期に返される可能性があります。この場合、システムコールは再開されます。トラッカーは、被追跡者が中断されたシステムコールを再実行することを観察します(または
restart_syscall(2)
トラッカーが使用している場合のシステムコール(再起動に別のメカニズムを使用するシステムコールの場合)PTRACE_SYSCALL
。システムコール(例:poll(2)
)信号が抑制された後は、信号が再開された後に再開することはできません。ただし、観察可能な信号が被追跡者に注入されていない場合でも、EINTRで特定のシステムコールが失敗する可能性があるカーネルバグがあります。。
基本的に、SIGWINCH
無視されますが、発信者が見ることができるepoll
ように聞こえます(再起動時にも)。poll
EINTR