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
If epollcreate1 fails (as I assume it might on an old kernel) then that first line is assigning a negative errno to epfd. Netpoll only checks that epfd != -1, which is why it passed -38 (-ENOSYS) to epollwait. Presumably netpollinit was about to overwrite the -38 with the result of epollcreate(1024), which was probably going to work, but it didn't get a chance.
More generally epfd is not itself an atomic variable. Instead there is an atomic netpollInited checked by func netpollinited. It looks like any call to netpoll should be guarded by an if netpollinited(). But the runtime has five calls and only three are guarded:
proc.go:1089: gp := netpoll(false) // non-blocking
proc.go:2247: if gp := netpoll(false); gp != nil { // non-blocking
proc.go:2387: gp := netpoll(true) // block until new work is available
proc.go:2422: if gp := netpoll(false); gp != nil {
proc.go:4242: gp := netpoll(false) // non-blocking - returns list of goroutines
1089 and 4242 need guards.
This is probably not reproducible in a test, but we should probably fix it anyway.
I received a private report of a crash in netpoll, running go 1.8.3 on an old linux kernel:
This was at program startup during the program's first attempted net.Dial.
It looks to me like there is a race between netpollinit and netpoll. Specifically, netpollinit does:
If epollcreate1 fails (as I assume it might on an old kernel) then that first line is assigning a negative errno to epfd. Netpoll only checks that epfd != -1, which is why it passed -38 (-ENOSYS) to epollwait. Presumably netpollinit was about to overwrite the -38 with the result of epollcreate(1024), which was probably going to work, but it didn't get a chance.
More generally epfd is not itself an atomic variable. Instead there is an atomic netpollInited checked by func netpollinited. It looks like any call to netpoll should be guarded by an
if netpollinited()
. But the runtime has five calls and only three are guarded:1089 and 4242 need guards.
This is probably not reproducible in a test, but we should probably fix it anyway.
/cc @aclements @ianlancetayor @dvyukov
The text was updated successfully, but these errors were encountered: