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/tools/gopls: nil Type crash in staticcheck #54762

Open
adonovan opened this issue Aug 29, 2022 · 6 comments
Open

x/tools/gopls: nil Type crash in staticcheck #54762

adonovan opened this issue Aug 29, 2022 · 6 comments
Assignees
Labels
gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@adonovan
Copy link
Member

adonovan commented Aug 29, 2022

This crash was observed on one builder run when the panic/recover was removed from analysis in gopls:

panic: nil type [recovered]
	panic: /workdir/gopath/src/golang.org/x/tools/internal/lsp/bug/bug.go:56: analysis SA4016 for package golang.org/x/tools/internal/lsp/rename/generics panicked: nil type

goroutine 93005 [running]:
golang.org/x/tools/internal/lsp/bug.Report({0xc009028900, 0x5e}, 0x0)
	/workdir/gopath/src/golang.org/x/tools/internal/lsp/bug/bug.go:71 +0x594
golang.org/x/tools/internal/lsp/bug.Errorf({0x1488298, 0x27}, {0xc00cdc6d38, 0x3, 0x3})
	/workdir/gopath/src/golang.org/x/tools/internal/lsp/bug/bug.go:56 +0x73
golang.org/x/tools/internal/lsp/cache.runAnalysis.func8.1()
	/workdir/gopath/src/golang.org/x/tools/internal/lsp/cache/analysis.go:368 +0x165
panic({0x12f23a0, 0x17aee00})
	/workdir/go/src/runtime/panic.go:890 +0x262
golang.org/x/exp/typeparams.computeTermSetInternal({0x0, 0x0}, 0x1385b00?, 0x0)
	/workdir/gopath/pkg/mod/golang.org/x/exp/typeparams@v0.0.0-20220722155223-a9213eeb770e/normalize.go:111 +0x1058
golang.org/x/exp/typeparams.NormalTerms({0x0?, 0x0})
	/workdir/gopath/pkg/mod/golang.org/x/exp/typeparams@v0.0.0-20220722155223-a9213eeb770e/normalize.go:78 +0x16e
honnef.co/go/tools/go/types/typeutil.NewTypeSet({0x0, 0x0})
	/workdir/gopath/pkg/mod/honnef.co/go/tools@v0.3.3/go/types/typeutil/typeparams.go:16 +0x3b
honnef.co/go/tools/go/types/typeutil.All({0x0, 0x0}, 0xc0021c1ce0?)
	/workdir/gopath/pkg/mod/honnef.co/go/tools@v0.3.3/go/types/typeutil/typeparams.go:99 +0x3c
honnef.co/go/tools/staticcheck.CheckSillyBitwiseOps.func1({0x17b3b48?, 0xc0021c1ce0})
	/workdir/gopath/pkg/mod/honnef.co/go/tools@v0.3.3/staticcheck/lint.go:2902 +0xc5
golang.org/x/tools/go/ast/inspector.(*Inspector).Preorder(0xc00a1fe600, {0xc00243d5b0?, 0x1, 0x431a70?}, 0xc00cdc75c0)
	/workdir/gopath/src/golang.org/x/tools/go/ast/inspector/inspector.go:77 +0x103
honnef.co/go/tools/analysis/code.Preorder(...)
	/workdir/gopath/pkg/mod/honnef.co/go/tools@v0.3.3/analysis/code/visit.go:16
honnef.co/go/tools/staticcheck.CheckSillyBitwiseOps(0xc008345110)
	/workdir/gopath/pkg/mod/honnef.co/go/tools@v0.3.3/staticcheck/lint.go:2966 +0xe5
golang.org/x/tools/internal/lsp/cache.runAnalysis.func8(0xc008b3e9a0, 0xc000487a00, 0xc001c5d440, 0xc008345110)
	/workdir/gopath/src/golang.org/x/tools/internal/lsp/cache/analysis.go:371 +0x117
FAIL	golang.org/x/tools/gopls/test	47.513s

The apparent cause is TypeOf(BinaryExpr) returning nil, which is then passed to NewTypeSet. The BinaryExpr in question is a "|" union operator over type constraints. Questions:

  • why isn't this deterministic? Is it a race against process exit, hence it only shows up on slower builders?
  • Is it a go/types bug? The analysis has RunDespiteErrors=false, so every expression should have a type.
@gopherbot gopherbot added Tools This label describes issues relating to any tools in the x/tools repository. gopls Issues related to the Go language server, gopls. labels Aug 29, 2022
@gopherbot gopherbot added this to the Unreleased milestone Aug 29, 2022
@adonovan
Copy link
Member Author

adonovan commented Aug 29, 2022

Another crash (also in staticcheck) reported by another single builder run:

panic: /workdir/gopath/src/golang.org/x/tools/internal/lsp/bug/bug.go:56: analysis SA1019 for package golang.org/x/tools/internal/lsp/rename/issue42134 panicked: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0xb11e1e]

goroutine 17408 [running]:
golang.org/x/tools/internal/lsp/bug.Report({0xc0098d4640, 0x98}, 0x0)
	/workdir/gopath/src/golang.org/x/tools/internal/lsp/bug/bug.go:71 +0x445
golang.org/x/tools/internal/lsp/bug.Errorf({0xf1dc31?, 0x31?}, {0xc001a98560?, 0xc001dd9ce0?, 0xc001a985c0?})
	/workdir/gopath/src/golang.org/x/tools/internal/lsp/bug/bug.go:56 +0x3f
golang.org/x/tools/internal/lsp/cache.runAnalysis.func8.1()
	/workdir/gopath/src/golang.org/x/tools/internal/lsp/cache/analysis.go:368 +0x10e
panic({0xdd7ec0, 0x16c80f0})
	/workdir/go/src/runtime/panic.go:884 +0x212
honnef.co/go/tools/staticcheck.CheckDeprecated.func3({0x11714b8?, 0xc001b4e2b8?}, 0x14?)
	/workdir/gopath/pkg/mod/honnef.co/go/tools@v0.3.3/staticcheck/lint.go:3178 +0x23e
golang.org/x/tools/go/ast/inspector.(*Inspector).Nodes(0xc004b61290, {0x0?, 0x16d4f60?, 0x203001?}, 0xc009d5f900)
	/workdir/gopath/src/golang.org/x/tools/go/ast/inspector/inspector.go:100 +0xad
honnef.co/go/tools/staticcheck.CheckDeprecated(0xc007ebf5f0)
	/workdir/gopath/pkg/mod/honnef.co/go/tools@v0.3.3/staticcheck/lint.go:3214 +0x1b1
golang.org/x/tools/internal/lsp/cache.runAnalysis.func8(0xdf0000?, 0xc007ebf5f0?, 0xc009874550, 0x510666?)
	/workdir/gopath/src/golang.org/x/tools/internal/lsp/cache/analysis.go:371 +0x76
golang.org/x/tools/internal/lsp/cache.runAnalysis({0x1175518, 0xc0027bbdc0}, 0xc003d76280, 0xc000152ea0, 0xc00ae68240, 0x5104d4?)
	/workdir/gopath/src/golang.org/x/tools/internal/lsp/cache/analysis.go:372 +0x888
golang.org/x/tools/internal/lsp/cache.(*snapshot).actionHandle.func1({0x1175518, 0xc0027bbdc0}, {0xed0a40?, 0xc003d76280})
	/workdir/gopath/src/golang.org/x/tools/internal/lsp/cache/analysis.go:168 +0xf0
golang.org/x/tools/internal/memoize.(*Promise).run.func2.1()
	/workdir/gopath/src/golang.org/x/tools/internal/memoize/memoize.go:187 +0xa9
runtime/trace.WithRegion({0x1175518?, 0xc0027bbdc0?}, {0xc00325c030, 0x21}, 0xc001a98f90)
	/workdir/go/src/runtime/trace/annotation.go:141 +0xe3
golang.org/x/tools/internal/memoize.(*Promise).run.func2()
	/workdir/gopath/src/golang.org/x/tools/internal/memoize/memoize.go:180 +0x145
created by golang.org/x/tools/internal/memoize.(*Promise).run
	/workdir/gopath/src/golang.org/x/tools/internal/memoize/memoize.go:179 +0x1ea
FAIL	golang.org/x/tools/gopls/test	6.121s

Apparently a nil ObjectOf on a SelectorExpr.Sel. None of these look related to the new generics logic.

@adonovan
Copy link
Member Author

adonovan commented Aug 31, 2022

Re-running the tests shows a great variety of crashes. https://source.cloud.google.com/results/invocations/48b434a2-c9e7-46a9-acde-57b5fc976081/targets/golang%2Ftools%2Fgopls-legacy%2Fpresubmit-116/log contains more evidence that this is a general race condition between two gopls subsystems: an analysis pass has a nil entry in the map of Results of its predecessor pass, Inspector.

panic: interface conversion: interface {} is nil, not *inspector.Inspector

goroutine 65570 [running]:
golang.org/x/tools/go/analysis/passes/structtag.run(0xc00d07f6c0, 0x3, 0xd357a0, 0xc00bc6f701, 0xc00d0b0ef0)
	/src/tools/go/analysis/passes/structtag/structtag.go:37 +0xfe
golang.org/x/tools/internal/lsp/cache.runAnalysis.func8(0xc00d07f6c0, 0xc00bc6f768)
	/src/tools/internal/lsp/cache/analysis.go:376 +0x52
golang.org/x/tools/internal/lsp/cache.runAnalysis(0x1039298, 0xc00d128b40, 0xc0023788c0, 0x149ff00, 0xc008475440, 0xc00d10f680, 0xc00d10f680)
	/src/tools/internal/lsp/cache/analysis.go:377 +0xa56
golang.org/x/tools/internal/lsp/cache.(*snapshot).actionHandle.func1(0x1039298, 0xc00d128b40, 0xe0da60, 0xc0023788c0, 0xc00c133640, 0xc0083d3658)
	/src/tools/internal/lsp/cache/analysis.go:168 +0x159
golang.org/x/tools/internal/memoize.(*Promise).run.func2.1()
	/src/tools/internal/memoize/memoize.go:187 +0xd7
runtime/trace.WithRegion(0x1039298, 0xc00d128b40, 0xc00d122540, 0x21, 0xc0083d3758)
	/usr/local/go/src/runtime/trace/annotation.go:141 +0xf8
golang.org/x/tools/internal/memoize.(*Promise).run.func2(0x1039298, 0xc00d128b40, 0xc00d05d6e0, 0xc00d0b0e80, 0xc00d10e960, 0xe0da60, 0xc0023788c0)
	/src/tools/internal/memoize/memoize.go:180 +0x14c
created by golang.org/x/tools/internal/memoize.(*Promise).run
	/src/tools/internal/memoize/memoize.go:179 +0x19a

@gopherbot
Copy link

gopherbot commented Aug 31, 2022

Change https://go.dev/cl/426802 mentions this issue: internal/lsp/cache: delete misleading Package.IllTyped method

@gopherbot
Copy link

gopherbot commented Aug 31, 2022

Change https://go.dev/cl/426803 mentions this issue: internal/lsp/cache: honor RunDespiteErrors=false

gopherbot pushed a commit to golang/tools that referenced this issue Aug 31, 2022
This method does not in fact report whether the package is ill-typed.
It actually reports whether any of three fields of pkg are nil.
They never are.
This does rather explain why type-error analyzers are executed
on (genuinely) ill-typed packages, despite the !IllTyped()
condition. And why analyzers that aren't prepared to handle
ill-typed code (!RunDespiteErrors) sometimes crash in production.

Updates golang/go#54762

Change-Id: I95421584bec68fb849b5ed52cc4e6d9b6bb679be
Reviewed-on: https://go-review.googlesource.com/c/tools/+/426802
Auto-Submit: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
gopherbot pushed a commit to golang/tools that referenced this issue Sep 1, 2022
This change prevents analysis from running on a package containing
any kind of error unless the analyzer has indicated that it is robust.
This is presumed to be the cause of several panics in production.

And a test.

Updates golang/go#54762

Change-Id: I9327e18ef8d7773c943ea45fc786991188358131
Reviewed-on: https://go-review.googlesource.com/c/tools/+/426803
Run-TryBot: Alan Donovan <adonovan@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
@jamalc jamalc modified the milestones: Unreleased, gopls/v0.10.0 Sep 1, 2022
@findleyr
Copy link
Contributor

findleyr commented Sep 9, 2022

Moving this to gopls/v0.10.1; I don't think we need to remove our panic recovery just yet.

@findleyr findleyr modified the milestones: gopls/v0.10.0, gopls/v0.10.1 Sep 9, 2022
@gopherbot
Copy link

gopherbot commented Sep 28, 2022

Change https://go.dev/cl/426018 mentions this issue: internal/lsp/cache: report analysis panics during testing

gopherbot pushed a commit to golang/tools that referenced this issue Sep 29, 2022
Report a bug when an analysis dependency is found to be
neither "vertical" (for facts) or "horizontal" (for results).
This has been observed in practise: the lookup from a package
ID to a package object is not consistent.

The bug report is suppressed for command-line-arguments
packages to see whether it occurs on ordinary packages too.

Also, add disabled logic to disable recovery and dump all
goroutines, for temporary use when debugging.

Unrelated things found during debugging:
- simplify package key used in analysis cache: the mode is
  always the same constant.
- move TypeErrorAnalyzers logic closer to where needed.

Updates golang/go#54655
Updates golang/go#54762

Change-Id: I0c2afd9ddd4fcc21748a03f8fa0769a2de09a56f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/426018
Reviewed-by: Robert Findley <rfindley@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

4 participants