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

os/exec: Cmd.ProcessState field not always populated after (*Cmd.Run) returns #56002

Closed
seh opened this issue Oct 2, 2022 · 1 comment
Closed
Assignees
Labels
Documentation FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@seh
Copy link
Contributor

seh commented Oct 2, 2022

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

go version go1.19.1 darwin/amd64

Does this issue reproduce with the latest release?

Yes.

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

go env Output
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/seh/Library/Caches/go-build"
GOENV="/Users/seh/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/seh/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/seh/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.19.1/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.19.1/libexec/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.19.1"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/seh/redacted/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/pm/0n7z4ljx1c78_d3vb379cqgc0000gn/T/go-build1922992552=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Read the documentation for the os/exec package's Cmd.ProcessState field. Note that it promises that its value will be available "after a call to Wait or Run.

Write a program that calls on the (*Cmd).Run method that invokes a nominated command that does not exist (that is, the Cmd.Path field's value does not designate a readable, executable file), then attempt to call methods on the *os.ProcessState field value that I expect to be present in the Cmd's "ProcessState" field.

What did you expect to see?

The Cmd's "ProcessField" value would be a non-nil pointer to an os.ProcessState.

What did you see instead?

My program panics dereferencing a nil pointer. The Cmd.ProcessState field remains nil after (*Cmd).Run returns.

Diagnosis

(*Cmd).Run is a macro operation that does the following:

  • Call (*Cmd).Start.
  • If that succeeds, call (*Cmd).Wait.

It turns out that only after (*Cmd).Wait returns—assuming that (*Cmd).Start was called first, and that it hasn't been called already—is the Cmd.ProcessState field populated. If (*Cmd).Run's invocation of (*Cmd).Start fails, then the field will not be populated.

The documentation is simple, but misleading. It would be more accurate to say that the Cmd.ProcessState field will be populated after (*Cmd).Run starts the command.

I came upon this discrepancy while debugging a program that panicked in this situation. It took a while to figure out that the path to the command I was nominating in the Cmd.Path field was wrong, such that (*Cmd).Start—invoked via (*Cmd).Run—was failing. I figured that (*Cmd).Run had returned, even if it had returned an error, so I could count on the Cmd.ProcessState field's value being available for use.

@ianlancetaylor ianlancetaylor added Documentation help wanted NeedsFix The path to resolution is known, but the work has not been done. labels Oct 3, 2022
@ianlancetaylor ianlancetaylor added this to the Backlog milestone Oct 3, 2022
@gopherbot
Copy link

Change https://go.dev/cl/437996 mentions this issue: os/exec: document ProcessState maybe nil when Start fails

@bcmills bcmills modified the milestones: Backlog, Go1.20 Oct 4, 2022
romaindoumenc pushed a commit to TroutSoftware/go that referenced this issue Nov 3, 2022
Wait or Run will populate its ProcessState when the command completes.

Fixes golang#56002.

Change-Id: I21547431f5d2d3e0fc0734fd1705421a0ac4209c
Reviewed-on: https://go-review.googlesource.com/c/go/+/437996
Auto-Submit: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
@golang golang locked and limited conversation to collaborators Oct 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Documentation FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

5 participants