Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: epollwait on fd 1 failed with 22 #68333

Closed
powellnorma opened this issue Jul 7, 2024 · 4 comments
Closed

runtime: epollwait on fd 1 failed with 22 #68333

powellnorma opened this issue Jul 7, 2024 · 4 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime.

Comments

@powellnorma
Copy link

Go version

go version go1.22.5 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/user/.cache/go-build'
GOENV='/home/user/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/user/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/user/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.5'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1055368833=/tmp/go-build -gno-record-gcc-switches'

What did you do?

I want to call a userspace program written in go from an LKM. I do this via call_usermodehelper. However the go program crashes.

You can reproduce it via this simple repository: https://github.com/powellnorma/go-crash

Any workarounds? Thank you.

What did you see happen?

runtime: epollwait on fd 1 failed with 22
fatal error: runtime: netpoll failed

runtime stack:
runtime.throw({0x4985aa?, 0x7ffcafbcd088?})
	/usr/local/go/src/runtime/panic.go:1077 +0x5c fp=0x7ffcafbcd010 sp=0x7ffcafbccfe0 pc=0x430b1c
runtime.netpoll(0xc000006d00?)
	/usr/local/go/src/runtime/netpoll_epoll.go:122 +0x34a fp=0x7ffcafbcd6a0 sp=0x7ffcafbcd010 pc=0x42d32a
runtime.startTheWorldWithSema()
	/usr/local/go/src/runtime/proc.go:1438 +0x37 fp=0x7ffcafbcd700 sp=0x7ffcafbcd6a0 pc=0x435dd7
runtime.gcStart.func3()
	/usr/local/go/src/runtime/mgc.go:749 +0x25 fp=0x7ffcafbcd728 sp=0x7ffcafbcd700 pc=0x415ec5
traceback: unexpected SPWRITE function runtime.systemstack
runtime.systemstack()
	/usr/local/go/src/runtime/asm_amd64.s:509 +0x4a fp=0x7ffcafbcd738 sp=0x7ffcafbcd728 pc=0x45ac2a

goroutine 1 [running]:
runtime.systemstack_switch()
	/usr/local/go/src/runtime/asm_amd64.s:474 +0x8 fp=0xc00005cba0 sp=0xc00005cb90 pc=0x45abc8
runtime.gcStart({0xc000500000?, 0x4a000?, 0x49fa0?})
	/usr/local/go/src/runtime/mgc.go:748 +0x3fc fp=0xc00005cc38 sp=0xc00005cba0 pc=0x415d3c
runtime.mallocgc(0x49fa0, 0x48d1c0, 0x1)
	/usr/local/go/src/runtime/malloc.go:1242 +0x76f fp=0xc00005cca0 sp=0xc00005cc38 pc=0x40bbaf
runtime.newarray(0x8?, 0xc00005cce8?)
	/usr/local/go/src/runtime/malloc.go:1346 +0x45 fp=0xc00005ccc8 sp=0xc00005cca0 pc=0x40be25
[..]

What did you expect to see?

No crash.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 7, 2024
@ianlancetaylor
Copy link
Member

It looks like when the kernel module runs the Go program, it runs it with (at least) file descriptor 1 not set to standard output. One effect is that the netpoll code uses descriptor 1 for the epoll descriptor. The program then uses Dup2 to clobber that descriptor.

There is no nothing we can change in Go to fix this, so closing this issue.

@ianlancetaylor ianlancetaylor closed this as not planned Won't fix, can't repro, duplicate, stale Jul 8, 2024
@powellnorma
Copy link
Author

Thank you for investigating. Does that mean it is not possible from within go to set the file descriptors 0-2 before the go runtime uses them? Wouldn't that mean that even when I don't change what FD 1 refers to (via Dup2) that it e.g. fmt.Printf would print to a FD its not supposed to interact/interfere with (the epoll FD)?

I guess in that case a workaround would be to write a wrapper program that sets those FDs before executing the application written in go.

@powellnorma
Copy link
Author

And what would be the best way to check for this situation? I could check if /proc/self/fd/1 points to anon_inode:[eventpoll] .. But is there something more elegant?

@ianlancetaylor
Copy link
Member

The Go os package on Unix systems does expect that it will be started with file descriptors 0, 1, and 2 set as they normally are. There is no support for programs that use the os package to run without those descriptors being set.

I don't know of a fully reliable way to detect the situation. It may work to syscall.Fstat descriptors 0, 1, and 2 and verify that they are all regular files or pipes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime.
Projects
None yet
Development

No branches or pull requests

3 participants