A handler installed with `SA_RESTART` does not restart the interrupted syscall
Maintainer thường phản hồi trong vòng 3 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 25/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- c, linux
- Lĩnh vực
- operating-systems
Hướng nghiên cứu
Start with syscall_restart_arm in src/syscall/proc.h, which today handles only execve on the thread group leader, and read the comment explaining why a signal delivered before resume cancels it. The fix depends on #384, since the handler frame carries the wire value in X8 rather than the syscall number. Build the reproducer from the issue, which should match Linux for FUTEX_WAIT and a pipe read (rc=0 and rc=1 respectively) instead of EINTR.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Linux restarts a syscall that a signal interrupted when the handler was installed with SA_RESTART and the syscall is one of the restartable ones in signal(7): read on a pipe or socket, futex FUTEX_WAIT without a timeout, wait4, accept and so on. elfuse returns EINTR to the guest instead. Measured for the two below; the others are untested.
The dispatcher has a restart path (syscall_restart_arm in src/syscall/proc.h), but it serves only an execve handed to the thread group leader, and a signal delivered before the guest resumes cancels it. The comment there gives the reason: the frame the handler returns through carries the wire value in X8 and not the syscall number, so a rewound PC would re-execute a different syscall. That is #384, which this depends on.
Reproducer: a SIGUSR1 handler installed with SA_RESTART, one thread parked in each wait, pthread_kill(SIGUSR1) at it, then the wait released (a FUTEX_WAKE after storing 1, a one-byte write).
#include <errno.h>
#include <linux/futex.h>
#include <pthread.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>
static uint32_t word;
static int pfd[2];
static volatile int handled;
static void on(int s)
{
(void) s;
handled++;
}
static void *w_futex(void *a)
{
(void) a;
long r = syscall(SYS_futex, &word, FUTEX_WAIT, 0, NULL, NULL, 0);
printf("futex FUTEX_WAIT: rc=%ld errno=%d\n", r, r < 0 ? errno : 0);
return NULL;
}
static void *w_read(void *a)
{
(void) a;
char c;
long r = read(pfd[0], &c, 1);
printf("read on a pipe: rc=%ld errno=%d\n", r, r < 0 ? errno : 0);
return NULL;
}
static void rel_futex(void)
{
word = 1;
syscall(SYS_futex, &word, FUTEX_WAKE, 1, NULL, NULL, 0);
}
static void rel_read(void)
{
write(pfd[1], "x", 1);
}
static void run(void *(*fn)(void *), void (*release)(void))
{
pthread_t t;
pthread_create(&t, NULL, fn, NULL);
usleep(200000);
pthread_kill(t, SIGUSR1);
usleep(300000);
release();
pthread_join(t, NULL);
}
int main(void)
{
struct sigaction sa;
memset(&sa, 0, sizeof sa);
sa.sa_handler = on;
sa.sa_flags = SA_RESTART;
sigaction(SIGUSR1, &sa, NULL);
pipe(pfd);
run(w_futex, rel_futex);
run(w_read, rel_read);
printf("handler ran %d times\n", handled);
return 0;
}
| wait | elfuse | Linux 6.12 under qemu |
|---|---|---|
futex(FUTEX_WAIT), no timeout |
rc=-1 errno=4 |
rc=0 |
read on an empty pipe |
rc=-1 errno=4 |
rc=1 |
The handler runs both times on both.
The waits signal(7) lists as never restarted (nanosleep, select, poll, epoll_wait among them) are out of scope: EINTR is right for those.
- Ngôn ngữ chính
- C
- Star
- 275
- Fork
- 29
- Merge trung bình
- 2 ngày 8 giờ
- Pull request đã merge (30 ngày)
- 17
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của sysprog21/elfuse
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 3 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 3 ngày
-
Let the vDSO move with mremapĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 40/100
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 30/100
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 3 ngày
Tất cả issue của sysprog21/elfuse
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
quickjs-ng/quickjs#1836 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
open-quantum-safe/liboqs#2637 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Go device SDK: Whisper transcriber keeps buffering and transcribing audio appended after Stop()Có thể đã có người làm @apoorvdarshan đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
BasedHardware/omi#22770 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
fido_do_ecdh() reports any getKeyAgreement failure as FIDO_ERR_INTERNALCó thể đã có người làm @brlumen đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
joncampbell123/dosbox-x#6698 ·
Maintainer thường phản hồi trong vòng 1 ngày