`wait4` and `waitid` never return `EINTR` when a handled signal arrives
メンテナーはふだん 3 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 54/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- c
調査の方向性
Start in src/syscall/proc.c at the polling loops in sys_wait4 and sys_waitid, then compare how the poll, futex and pipe paths use signal_claim_interruption(). The issue describes the required behavior for handlers with and without SA_RESTART and provides a reproducer. Add regression coverage for wait4(pid), wait4(-1) and waitid, checking EINTR without SA_RESTART and successful reap with it.
索引モデルが issue の本文から書いたものです。
説明
On Linux, a blocking wait4 or waitid sleeps in do_wait (kernel/exit.c) with TASK_INTERRUPTIBLE and leaves the loop with -ERESTARTSYS once a signal is pending. Signal delivery turns that into EINTR when the handler lacks SA_RESTART, and restarts the wait when it has it. Under elfuse the wait ignores the signal and returns only when the child exits: the polling loops in sys_wait4 and sys_waitid (src/syscall/proc.c) check thread_stop_requested() but never signal_claim_interruption(), which the poll, futex and pipe paths use for the same purpose.
Reproducer (the child signals the parent at 0.2 s and exits 1 s later; the handler has no SA_RESTART):
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
static void on_usr1(int sig)
{
(void) sig;
}
static double now(void)
{
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return t.tv_sec + t.tv_nsec / 1e9;
}
static void run(const char *name, int mode)
{
pid_t child = fork();
if (child == 0) {
usleep(200000);
kill(getppid(), SIGUSR1);
sleep(1);
_exit(0);
}
double t0 = now();
int status;
siginfo_t si;
long ret;
if (mode == 0)
ret = waitpid(child, &status, 0);
else if (mode == 1)
ret = waitpid(-1, &status, 0);
else
ret = waitid(P_PID, child, &si, WEXITED);
int err = errno;
printf("%-10s ret=%ld %s after %.2fs\n", name, ret,
ret < 0 ? strerror(err) : "", now() - t0);
if (ret < 0)
waitpid(child, &status, 0);
}
int main(void)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = on_usr1;
sigaction(SIGUSR1, &sa, NULL);
run("wait4(pid)", 0);
run("wait4(-1)", 1);
run("waitid", 2);
return 0;
}
wait4(pid) |
wait4(-1) |
waitid |
|
|---|---|---|---|
elfuse c2785c7 |
child pid after 1.2 s | child pid after 1.2 s | 0 after 1.2 s |
| Linux 6.12 under qemu | -1, EINTR after 0.2 s |
-1, EINTR after 0.2 s |
-1, EINTR after 0.2 s |
The SA_RESTART half needs its own handling: elfuse has no general ERESTARTSYS path, so a loop that starts honoring the claimed signal has to keep waiting when that signal's handler has SA_RESTART. A regression test needs the child to stay alive until the handler releases it, and should cover EINTR without SA_RESTART and a successful reap with it, for wait4(pid), wait4(-1) and waitid.
Found by jserv in https://github.com/sysprog21/elfuse/pull/460#discussion_r4348510702: the race fixed there never showed under elfuse for this reason.
- 主要言語
- C
- スター
- 275
- フォーク
- 29
- 平均マージ
- 2日 22時間
- マージ済み PR(30日)
- 18
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
sysprog21/elfuse のほかの issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
メンテナーはふだん 3 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 3 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
メンテナーはふだん 3 日以内に返信
-
bug
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
メンテナーはふだん 3 日以内に返信
-
bug
難易度 4/5 3〜5日 初心者へのやさしさ 55/100
メンテナーはふだん 3 日以内に返信
sysprog21/elfuse の issue をすべて見る
似ている issue
-
難易度 1/5 1〜3時間 初心者へのやさしさ 82/100
-
[pico][astrocade] emu/apply.sh edits src/mame/midway/astrohome.cpp, which current MAME has in bally/オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 83/100
FujiNetWIFI/fujinet-firmware#2120 ·
メンテナーはふだん 1 日以内に返信
-
Bug Status: Needs Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 73/100
php/php-src#24552 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
sumatrapdfreader/sumatrapdf#6403 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100