Skip to content

os/exec: CommandContext should return "context canceled" when the context is canceled #69585

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

Closed
HirazawaUi opened this issue Sep 23, 2024 · 2 comments

Comments

@HirazawaUi
Copy link

Go version

go version go1.23.0 darwin/arm64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/bing/Library/Caches/go-build'
GOENV='/Users/bing/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/bing/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/bing/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/darwin_arm64'
GOVCS=''
GOVERSION='go1.22.1'
GCCGO='gccgo'
AR='ar'
CC='clang'
CXX='clang++'
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 -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/cl/v9c2b59x40ldmf9vr6hrx8mw0000gn/T/go-build3833267051=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

I ran the following test code, expecting it to terminate the command as intended

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
	defer cancel()

	if err := exec.CommandContext(ctx, "sleep", "5").Run(); err != nil {
		fmt.Println(err)
	}
}

What did you see happen?

In fact, it did terminate the command, but the returned error was signal: killed. I don't think this is the correct error output.

What did you expect to see?

I believe it should return "context canceled,". Every developer clearly understands that the lifecycle of this command is managed by their own context, and the command would terminate due to the cancel of the context derived from their Go program.

However, "signal: killed" is an unexpected error, and it can be triggered for various reasons. This error makes the lifecycle management of the command unclear (at least to me). I'm not even sure why the command was terminated—maybe it was due to an OOM kill? Or perhaps it was manually terminated by the user? I might need to check the system logs to confirm this.

The relevant code can be found at

go/src/os/exec/exec.go

Lines 928 to 939 in 7c72dc7

var timer *time.Timer
if c.ctxResult != nil {
watch := <-c.ctxResult
timer = watch.timer
// If c.Process.Wait returned an error, prefer that.
// Otherwise, report any error from the watchCtx goroutine,
// such as a Context cancellation or a WaitDelay overrun.
if err == nil && watch.err != nil {
err = watch.err
}
}

From the comments, I understand this is an expected error handling behavior. Should we revisit this behavior based on the points above for further discussion?

@seankhliao
Copy link
Member

I believe the current setup is appropriate, a timeout masks any more detailed error, and it may be that the process chooses to handle the termination signal gracefully so the error isn't always a plain killed.

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Sep 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants