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

x/playground: exec: "gcc": executable file not found in $PATH #26307

Closed
bradfitz opened this issue Jul 10, 2018 · 16 comments
Closed

x/playground: exec: "gcc": executable file not found in $PATH #26307

bradfitz opened this issue Jul 10, 2018 · 16 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@bradfitz
Copy link
Contributor

I'm getting errors looking for gcc (!?) on the playground:

https://play.golang.org/p/5GlPtcESJm

# net
exec: "gcc": executable file not found in $PATH
Go vet exited.

screen shot 2018-07-09 at 7 32 22 pm

/cc @andybons

@bradfitz bradfitz added the NeedsFix The path to resolution is known, but the work has not been done. label Jul 10, 2018
@bradfitz bradfitz added this to the Unreleased milestone Jul 10, 2018
@ysmolski
Copy link
Member

ysmolski commented Jul 10, 2018

Reproduced this in local docker image.
"go vet -x" wants to do this:

mkdir -p $WORK/b067/
cd /usr/local/go/src/net
CGO_LDFLAGS='"-g" "-O2"' /usr/local/go/pkg/tool/linux_amd64/cgo -objdir $WORK/b067/ -importpath net -- -I $WORK/b067/ -g -O2 ./cgo_linux.go ./cgo_resnew.go ./cgo_socknew.go ./cgo_unix.go
cd $WORK
gcc -fno-caret-diagnostics -c -x c - || true

but it fails on gcc line.

Why does vet compile net package in cgo mode while we have CGO_ENABLED=0 set in Dockerfile?

@ysmolski
Copy link
Member

Changing from "go vet" to "go tool vet" in vet.go fixes problem in my local machine. Some day I might learn what is the difference between those.

@ysmolski
Copy link
Member

And another fix would be:

	cmd := exec.Command("go", "vet", in)
	cmd.Env = append(cmd.Env, "CGO_ENABLED=0")

Meaning that "go vet" does not remember CGO_ENABLED variable set during the build of go tools.

@ianlancetaylor
Copy link
Member

If the Go toolchain was built with CGO_ENABLED=0, then that should be the default for go vet. Can you find out what the generated file go/build/zcgo.go looks like? What is the value of defaultCGO_ENABLED in that file?

@ysmolski
Copy link
Member

Playground tools are compiled this way:

Is src/go/build/zcgo.go modified during tools rebuild?

/usr/local/go# cat VERSION
go1.10.2
/usr/local/go# cat src/go/build/zcgo.go
// Code generated by go tool dist; DO NOT EDIT.

package build

const defaultCGO_ENABLED = ""

var cgoEnabled = map[string]bool{
	"android/386": true,
	"android/amd64": true,
	"android/arm": true,
	"android/arm64": true,
	"darwin/386": true,
	"darwin/amd64": true,
	"darwin/arm": true,
	"darwin/arm64": true,
	"dragonfly/amd64": true,
	"freebsd/386": true,
	"freebsd/amd64": true,
	"linux/386": true,
	"linux/amd64": true,
	"linux/arm": true,
	"linux/arm64": true,
	"linux/mips": true,
	"linux/mips64": true,
	"linux/mips64le": true,
	"linux/mipsle": true,
	"linux/ppc64le": true,
	"linux/s390x": true,
	"netbsd/386": true,
	"netbsd/amd64": true,
	"netbsd/arm": true,
	"openbsd/386": true,
	"openbsd/amd64": true,
	"solaris/amd64": true,
	"windows/386": true,
	"windows/amd64": true,
}

@ianlancetaylor
Copy link
Member

The zcgo.go file is created while running make.bash (by mkzcgo in cmd/dist/build.go) and should never be modified afterward. Seeing defaultCGO_ENABLED set to the empty string suggests that CGO_ENABLED was not set (or was set to the empty string) when make.bash was run. I can't tell from the above: is CGO_ENABLED=0 expected to be set while running make.bash? If so, I can't explain what you are seeing.

@ysmolski
Copy link
Member

ysmolski commented Jul 10, 2018 via email

@ysmolski
Copy link
Member

Running vet directly in the docker image:

root@58a9d65c6c00:/go/src/s# go vet net.go
# net
exec: "gcc": executable file not found in $PATH
root@58a9d65c6c00:/go/src/s# go tool vet net.go
root@58a9d65c6c00:/go/src/s# GOOS=nacl GOARCH=amd64p32 go vet net.go
root@58a9d65c6c00:/go/src/s# GOOS=nacl GOARCH=amd64p32 go tool vet net.go

It was built this way:

ENV CGO_ENABLED=0
<<skipped>>
# Get the Go binary.
RUN curl -sSL https://dl.google.com/go/go$GO_VERSION.linux-amd64.tar.gz -o /tmp/go.tar.gz
RUN curl -sSL https://dl.google.com/go/go$GO_VERSION.linux-amd64.tar.gz.sha256 -o /tmp/go.tar.gz.sha256
RUN echo "$(cat /tmp/go.tar.gz.sha256) /tmp/go.tar.gz" | sha256sum -c -
RUN tar -C /usr/local/ -vxzf /tmp/go.tar.gz
# Make a copy for GOROOT_BOOTSTRAP, because we rebuild the toolchain and make.bash removes bin/go as its first step.
RUN cp -R /usr/local/go $GOROOT_BOOTSTRAP
# Apply the fake time and fake filesystem patches.
RUN patch /usr/local/go/src/runtime/rt0_nacl_amd64p32.s /usr/local/playground/enable-fake-time.patch
RUN patch -p1 -d /usr/local/go </usr/local/playground/strict-time.patch
RUN cd /usr/local/go && go run misc/nacl/mkzip.go -p syscall /usr/local/playground/fake_fs.lst src/syscall/fstest_nacl.go
# Re-build the Go toolchain.
RUN cd /usr/local/go/src && GOOS=nacl GOARCH=amd64p32 ./make.bash --no-clean

Here we cross compile go and toolchain, but I am not sure if the native go is getting recompiled too using CGO_ENABLED=0. It seems it is not, but the it looks like it's datetime is get updated:

root@58a9d65c6c00:/usr/local/go/bin# ls -l
total 29728
-rwxr-xr-x 1 root root 11235730 Jul 10 17:06 go
-rwxr-xr-x 1 root root 15727868 Apr 30 20:34 godoc
-rwxr-xr-x 1 root root  3468455 Jul 10 17:06 gofmt
drwxr-xr-x 2 root root     4096 Jul 10 17:07 nacl_amd64p32

@ianlancetaylor
Copy link
Member

My guess is that because you are running make.bash --no-clean the existing go/build package, which was built without CGO_ENABLED being set, is reused. So although you do get a new go command, it is still one that defaults to CGO_ENABLED unset, and therefore defaults to actually using cgo.

@ianlancetaylor
Copy link
Member

In any case explicitly setting CGO_ENABLED=0 when running go vet seems appropriate. It may also be appropriate to set GOOS and GOARCH.

@gopherbot
Copy link
Contributor

Change https://golang.org/cl/123136 mentions this issue: playground: disable cgo in the vet tool

@cuonglm
Copy link
Member

cuonglm commented Jul 11, 2018

@ysmolsky

Changing from "go vet" to "go tool vet" in vet.go fixes problem in my local machine. Some day I might learn what is the difference between those.

From 1.9 to 1.10, go vet compile packages so it know the types, go tool vet does not.

@ianlancetaylor

If the Go toolchain was built with CGO_ENABLED=0, then that should be the default for go vet

How to verify it?

I build playground image with latest master, run the container and here's the strace output:

root@13fe25fb197c:/usr/local/go/pkg/tool/linux_amd64# strace -v -f -s 8192 -e trace=execve sh -c 'go vet net'
execve("/bin/sh", ["sh", "-c", "go vet net"], ["HOSTNAME=13fe25fb197c", "TERM=xterm", "OLDPWD=/usr/local/go/src", "PATH=/usr/local/go/bin:/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "PWD=/usr/local/go/pkg/tool/linux_amd64", "SHLVL=1", "HOME=/root", "GOPATH=/go", "_=/usr/bin/strace"]) = 0
Process 1353 attached
[pid  1353] execve("/usr/local/go/bin/go", ["go", "vet", "net"], ["HOSTNAME=13fe25fb197c", "SHLVL=1", "OLDPWD=/usr/local/go/src", "HOME=/root", "_=/usr/bin/strace", "TERM=xterm", "PATH=/usr/local/go/bin:/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "GOPATH=/go", "PWD=/usr/local/go/pkg/tool/linux_amd64"]) = 0
Process 1354 attached
Process 1355 attached
Process 1356 attached
Process 1357 attached
Process 1358 attached
Process 1359 attached
Process 1360 attached
Process 1361 attached
Process 1362 attached
Process 1363 attached
Process 1364 attached
Process 1365 attached
[pid  1365] execve("/usr/local/go/pkg/tool/linux_amd64/compile", ["/usr/local/go/pkg/tool/linux_amd64/compile", "-V=full"], ["HOSTNAME=13fe25fb197c", "SHLVL=1", "OLDPWD=/usr/local/go/src", "HOME=/root", "_=/usr/bin/strace", "TERM=dumb", "PATH=/usr/local/go/bin:/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "GOPATH=/go", "PWD=", "GOARCH=amd64", "GOCACHE=/root/.cache/go-build", "GOHOSTARCH=amd64", "GOHOSTOS=linux", "GOOS=linux", "GOROOT=/usr/local/go", "GOTOOLDIR=/usr/local/go/pkg/tool/linux_amd64", "GCCGO=gccgo", "CC=gcc", "CXX=g++", "CGO_ENABLED=1"]) = 0

go vet net runs without CGO_ENABLED in its environment.

compile is called with CGO_ENABLED=1, which tool set it?

@cuonglm
Copy link
Member

cuonglm commented Jul 11, 2018

@ysmolsky

Why does vet compile net package in cgo mode while we have CGO_ENABLED=0 set in Dockerfile?

Because we don't set it in final stage https://github.com/golang/playground/blob/master/Dockerfile#L172

@ianlancetaylor
Copy link
Member

In the execution of cmd/compile, CGO_ENABLED=1 is being passed because MkEnv in cmd/go/internal/envcmd/env.go is seeing that cfg.BuildContext.CgoEnabled is true. The setting there gets put into the environment by code in cmd/go/main.go. cfg.BuildContext is initialized from build.Default in the go/build package. build.Default is set from defaultContext in go/build/build.go. There you can see that CgoEnabled is set from the value in zcgo.go which should reflect the setting of CGO_ENABLED at the time that the package was built.

@andybons
Copy link
Member

This still appears to be broken: https://20180711t144932-dot-play-dot-golang-org.appspot.com/p/5GlPtcESJm

@andybons andybons reopened this Jul 11, 2018
@andybons
Copy link
Member

Nevermind. Need to clear the cache 🤦‍♂️

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

6 participants