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

syscall: Syscall occasionally returns incorrect result #51404

Closed
secDre4mer opened this issue Mar 1, 2022 · 3 comments
Closed

syscall: Syscall occasionally returns incorrect result #51404

secDre4mer opened this issue Mar 1, 2022 · 3 comments

Comments

@secDre4mer
Copy link
Contributor

What version of Go are you using (go version)?

$ go version
go version go1.17.7 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/max/.cache/go-build"
GOENV="/home/max/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/max/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/max/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/lib/go-1.17"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/lib/go-1.17/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.7"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/max/workspace/minimalsetpriority/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build549664404=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Compile the following program: https://go.dev/play/p/MQfIQDsSuCv

Run it as root on a Linux system.

What did you expect to see?

The program should never terminate since Getpriority will always return the priority that was set previously by Setpriority.

What did you see instead?

After a few seconds, the program terminates, stating that Getpriority returned an incorrect value.

This does not happen if runtime.LockOSThread is called at the start of main.

Presumably, the incorrect value originates from a context switch in the runtime right after the syscall
(strace output seems to support that something happens at that time, but I'm not sure what exactly besides a lot of futex syscalls).

@mengzhuo mengzhuo changed the title affected/package: syscall: Syscall occasionally returns incorrect result syscall: Syscall occasionally returns incorrect result Mar 1, 2022
@mengzhuo
Copy link
Contributor

mengzhuo commented Mar 1, 2022

getpriority returns a thread based value, goroutine will runs on different threads by default

On success, getpriority() returns the calling thread's nice
value, which may be a negative number.

https://man7.org/linux/man-pages/man2/setpriority.2.html

runtime.LockOSThread will lock this running gorouine ONLY runs on current thread.

Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only.

For questions please refer to https://github.com/golang/go/wiki/Questions

@mengzhuo mengzhuo closed this as completed Mar 1, 2022
@secDre4mer
Copy link
Contributor Author

Hi @mengzhuo , thanks for the quick response.

Based on your response, this is likely outside Golang scope. I don't quite understand (yet) why this happens, though.

In the example, setpriority sets the priority on the full process scope, as indicated by PRIO_PROCESS; according to the man page, this will affect all underlying threads.

The nice value set with setpriority() shall be applied to the process. If the process is multi-threaded, the nice value shall affect all system scope threads in the process.

https://linux.die.net/man/3/setpriority

Also, getpriority states in its description that it returns the process's priority, not the thread's priority:

The scheduling priority of the process, process group, or user, as indicated by which and who is obtained with the getpriority() call and set with the setpriority() call.

https://man7.org/linux/man-pages/man2/setpriority.2.html

Based on this, even if the goroutine runs on a different thread, the priority should be changed, right?

@secDre4mer
Copy link
Contributor Author

I found another indicator that this might actually be a kernel bug and not a Golang bug:

When calling getpriority, using 0 or the current pid as who parameter should be equivalent, according to the man page:

A zero value for who denotes (respectively) the calling process, the process group of the calling process, or the real user ID of the calling process.

https://man7.org/linux/man-pages/man2/setpriority.2.html

However, in practice, when using the PID instead of 0, the program now runs indefinitely, even without LockOSThread.

Playground link: https://go.dev/play/p/iuzD-oizh7d

@golang golang locked and limited conversation to collaborators Mar 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants