golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.97k stars 17.53k forks source link

x/tools/go/ssa: crashes on code containing generics #54086

Open MadhavJivrajani opened 2 years ago

MadhavJivrajani commented 2 years ago

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

$ go version
go version go1.19rc2 linux/amd64

Does this issue reproduce with the latest release?

Yes, with go1.19rc2.

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/nikhita/.cache/go-build"
GOENV="/home/nikhita/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/nikhita/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/nikhita/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org/,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.19rc2"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/nikhita/go/src/k8s.io/kubernetes/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 -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build4046507775=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Kubernetes runs a pre-submit which makes use of levee. The script for which can be found here: https://github.com/kubernetes/kubernetes/blob/master/hack/verify-govet-levee.sh

What did you expect to see?

Expected no crashes as per https://github.com/golang/go/issues/48525#issuecomment-1128385150

What did you see instead?

After bumping the test image to 1.19rc2, the above mentioned job started panicing, panic starting from x/tools/go/analysis/unitchecker and ending in x/tools/go/ssa. The entire stack trace can be found here as part of the logs: https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/directory/pull-kubernetes-verify-govet-levee/1552157434636668928

Reproducing the issue

To reproduce it locally, running ./hack/verify-govet-levee.sh on Kubernetes master after switching to go1.19rc2 should do it.

Misc info

https://github.com/golang/go/issues/48525 was an issue for the Go 1.18 timeframe as well, but the failing job above worked fine before. I'm not sure why this happens after switching to go1.19. Could this be because of go1.19 introducing generics in the stdlib?

The reason I list the above reason is because in the logs we see panics in the following two instances:

instances of generics in the stdlib

panic: no concrete method: func (*sync/atomic.Pointer[go/token.File]).CompareAndSwap(old *go/token.File, new *go/token.File) (swapped bool)

and

panic: no concrete method: func (*crypto/elliptic.nistCurve[*crypto/internal/nistec.P224Point]).Add(x1 *math/big.Int, y1 *math/big.Int, x2 *math/big.Int, y2 *math/big.Int) (*math/big.Int, *math/big.Int)

For more details around this failure and the timeline of merges in Kubernetes that led to them, please see: https://github.com/kubernetes/kubernetes/issues/111452


cc @timothy-king Since you were working on the generics support for SSA cc @nikhita @dims @liggitt @palnabarun

timothy-king commented 2 years ago

kubernetes/hack/tools is using x/tools at 77aa08bb151a:

# From go/src/k8s.io/kubernetes/hack/tools
$ go list -m golang.org/x/tools
golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a

You need to sync past at least the last relevant commit for https://github.com/golang/go/issues/48525#issuecomment-1128385150.

You can upgrade to the v0.1.12 release as follows:

# From go/src/k8s.io/kubernetes/hack/tools
$ go get golang.org/x/tools@v0.1.12
$ go mod tidy

Running $ ./hack/verify-govet-levee.sh I now see:

# From go/src/k8s.io/kubernetes
$ ./hack/verify-govet-levee.sh
[...]

+++ [0803 23:29:23] Building go targets for linux/amd64
    k8s.io/kubernetes/hack/make-rules/helpers/go2make (non-static)
# sync/atomic
unexpected type received: *types.TypeParam T; please report this issue
unexpected type received: *types.TypeParam T; please report this issue
unexpected type received: *types.TypeParam T; please report this issue
unexpected type received: *types.TypeParam T; please report this issue
# crypto/elliptic
unexpected type received: *types.TypeParam Point; please report this issue

This addresses the crashes you are seeing. This is now https://github.com/google/go-flow-levee/issues/323.

In the long term levee should: 1) update its x/tools dependency (quick n easy) and 2) support type parameters. A stop gap to simply ignore type params and generic functions/methods seems easy. More is blocked on https://github.com/golang/go/issues/48525#issuecomment-1190816141 for now.

dims commented 2 years ago

@timothy-king thanks for the analysis.

gopherbot commented 2 years ago

Change https://go.dev/cl/422414 mentions this issue: go.mod: update x/tools to HEAD