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

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions