You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What steps will reproduce the problem?
http://play.golang.org/p/jqEzJKsSCD
go build bork.go
strace -f ./bork
for some weird reason the problem only shows up when you run under strace
in my bigger internal test, I saw this without stracing it
What is the expected output?
nothing
What do you see instead?
strace shows: epoll_ctl(6, EPOLL_CTL_ADD, 4, {...}) = -1 EEXIST (File exists)
panic: errno -17
goroutine 1 [running]:
main.newClientServerConn(0xc200000300, 0x0, 0x0)
/home/alberts/bork.go:143 +0x135
main.main()
/home/alberts/bork.go:153 +0x34
goroutine 2 [syscall]:
goroutine 7 [chan send]:
main.func·001()
/home/alberts/bork.go:138 +0xb9
created by main.newClientServerConn
/home/alberts/bork.go:139 +0xdb
Which compiler are you using (5g, 6g, 8g, gccgo)?
6g
Which operating system are you using?
linux
Which version are you using? (run 'go version')
tip
Please provide any additional information below.
revision 631535312f2b works
revision f9c03cd9bd84 introduced the bug
Thanks!
The following C programs fails with the same error:
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define CHECK(...) if ((__VA_ARGS__) >= 0); else \
exit(printf("FAILED on line %d: %s\n", __LINE__, strerror(errno)))
int main() {
int epfd, fds[2], fd1, fd2;
struct epoll_event ev;
CHECK(socketpair(AF_LOCAL, SOCK_STREAM, 0, fds));
CHECK(epfd = epoll_create1(0));
ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
CHECK(epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &ev));
CHECK(fd1 = dup(fds[0]));
CHECK(close(fds[0]));
CHECK(close(fds[1]));
#ifndef FIX
CHECK(fd2 = dup(fd1));
CHECK(epoll_ctl(epfd, EPOLL_CTL_ADD, fd2, &ev));
CHECK(close(fd2));
#else
(void)fd2;
CHECK(epoll_ctl(epfd, EPOLL_CTL_ADD, fd1, &ev));
#endif
CHECK(close(fd1));
return 0;
}
And if you compile it with -DFIX, then it does not.
It seems the be a serious misdesign of epoll API:
http://lwn.net/Articles/430804/
It makes the 'automatic unregistration on close()' feature (which I was relying on)
basically useless (misbehaving in cases like this).
Fix is coming.
Attachments:
The text was updated successfully, but these errors were encountered: