Skip to content

os/exec: Cmd.Start should fail when called more than once #76746

@everzakov

Description

@everzakov

Go version

go version go1.24.6 linux/amd64

Output of go env in your module/workspace:

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

What did you do?

I'm trying to start again Cmd if the first try was unsuccessful. However, Cmd.Wait() returns an error if it is OK with command.

The cause is that the goroutines are saved from the first try but the pipes are closed. The process is not started that's why parentsIOPipes will be closed. And if this function try to read from pipe then the we will get the error.

Example:

package main

import (
	"bytes"
	"fmt"
	"os/exec"
)

func main() {
	var stdout2 bytes.Buffer
	cmd := exec.Command("bash", "-c", "sleep 10")
	cmd.Stdout = &stdout2

	var str string
	// Set 0 to env to return err in cmd.Start()
	str = string([]byte{0})
	cmd.Env = []string{str}

	err := cmd.Start()
	fmt.Println(err)

	cmd.Env = nil
	err = cmd.Start()
	fmt.Println(err)

	err = cmd.Wait()
	fmt.Println(err)
}

Example where cmd.Start is called twice - https://github.com/opencontainers/runc/blob/v1.4.0/libcontainer/process_linux.go#L370

What did you see happen?

vboxuser@vboxuser:~/golang-bug$ go run main.go 
exec: environment variable contains NUL
<nil>
read |0: file already closed

What did you expect to see?

Cmd.Wait() do not return an error. If c.goroutine = nil is set in defer function then the error is not returned.

vboxuser@vboxuser:~/golang-bug$ go run main.go 
exec: environment variable contains NUL
<nil>
<nil>

Metadata

Metadata

Assignees

Labels

BugReportIssues describing a possible bug in the Go implementation.NeedsFixThe path to resolution is known, but the work has not been done.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions