go: os: File implicitly closed when garbage-collected due to runtime finalizer but this behavior is not documented
What version of Go are you using (go version)?
$ go version go 1.15.2
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env)?
Linux and macOS.
What did you do?
Code: https://play.golang.org/p/YmHIIc7sha4
Note: This does not reproduce in go playground, but can reproduce on my mac/linux.
What did you expect to see?
No panic.
What did you see instead?
panic: bad file descriptor
Reason
I found that this is because there’s an implicitly close call when the file object is garbage-collected.
In os/file_unix.go:
func newFile(fd uintptr, name string, kind newFileKind) *File {
...
runtime.SetFinalizer(f.file, (*file).close)
return f
}
What do I expect
I know there’s thousands of method to avoid being garbage-collected such as runtime.KeepAlive, but I think this is unreasonable, either this behaviour should be removed or the file object should not be garbage-collected.
If a user forgets to call file.Close, the memory should be leaking.
Also, this behaviour isn’t documented anywhere.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 19 (15 by maintainers)
I think that the File.Fd method should be deprecated in favor of RawConn.Control and perhaps a new RawConn.MultiControl. We cannot remove File.Fd due to the Go 1 promise, but it is very hard to use correctly. It is what I would call a “foot gun”.