Open OverOrion opened 2 years ago
The gist.github.com link gives a 404 -- can you repost the reproducer somewhere? (Preferably verbatim in a comment in this issue.)
@OverOrion do you still happen to have the reproducer for this?
Unfortunately not :(
@MrAnno Do you still have the reproducer, given that it was posted under your gist.github.com?
I don't have it, but I think I remember what to do. I'll try to recreate the reproducer next week.
#0 0x000000080058b41a in thr_kill () from /lib/libc.so.7
#1 0x0000000800504e64 in raise () from /lib/libc.so.7
#2 0x00000008005b56f9 in abort () from /lib/libc.so.7
#3 0x0000000800448a6e in iv_fatal (fmt=<optimized out>) at iv_fatal.c:57
#4 0x000000080044fcd4 in iv_fd_kqueue_poll (st=0x800c09000, active=0x7fffffffe960, abs=0x0) at iv_fd_kqueue.c:212
#5 0x000000080044b3e6 in iv_fd_poll_and_run (st=0x800c09000, abs=0x0) at iv_fd.c:205
#6 0x000000080044cf90 in iv_main () at iv_main_posix.c:112
#7 0x0000000000400d6e in main () at test.c:55
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <iv.h>
void fatal(const char* msg)
{
perror(msg);
exit(1);
}
void write_fd(void* c)
{
struct iv_fd* fd = (struct iv_fd*) c;
const char* buf = "hello\n";
int rc = write(fd->fd, buf, strlen(buf) + 1);
if (rc < 0)
iv_fd_unregister(fd);
}
int main()
{
iv_init();
int pp[2];
if (pipe(pp) < 0)
fatal("pipe()");
pid_t pid = fork();
if (pid < 0)
fatal("fork()");
if (pid == 0) {
close(pp[1]);
close(pp[0]);
return 0;
}
close(pp[0]);
struct iv_fd fd;
IV_FD_INIT(&fd);
fd.fd = pp[1];
fd.cookie = &fd;
fd.handler_out = write_fd;
iv_fd_register(&fd);
iv_main();
iv_deinit();
close(pp[1]);
int rc;
if (wait(&rc) < 0)
fatal("wait()");
return 0;
}
The attached reproducer code spawns two processes, one of them polls a perfectly valid pipe fd for writing using ivykis, and the child process would be responsible for reading, but for an easier reproduction, the child just closes the pipe and exits. (Reading and then closing would result in the same abort.)
https://gist.github.com/MrAnno/0a6dd9572e8a7a981996654ccd3e5e08
Running it yields the following backtrace:
I believe ivykis incorrectly reports fatal errors in case a kevent() call returns EV_ERROR on the file description: https://github.com/buytenh/ivykis/blob/f1b14555fb0b5d9acfbcfaf35b1313bb28d858c2/src/iv_fd_kqueue.c#L208-L214
The epoll implementation, for example, reports these kind of errors as non-fatal using the error callback: https://github.com/buytenh/ivykis/blob/f1b14555fb0b5d9acfbcfaf35b1313bb28d858c2/src/iv_fd_epoll.c#L185-L186