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: crash during internal/imports.scanDirForPackage (crash) #67156

Closed
Sangwaniya opened this issue May 3, 2024 · 26 comments
Closed
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

@Sangwaniya
Copy link

gopls version: v0.15.3/go1.21.6
gopls flags:
update flags: proxy
extension version: 0.41.4
environment: Visual Studio Code win32
initialization error: undefined
issue timestamp: Thu, 02 May 2024 17:33:19 GMT
restart history:
Thu, 02 May 2024 17:30:10 GMT: activation (enabled: true)

ATTENTION: PLEASE PROVIDE THE DETAILS REQUESTED BELOW.

Describe what you observed.

panic: runtime error: slice bounds out of range [45:44]

goroutine 7611 [running]:
golang.org/x/tools/internal/imports.(*ModuleResolver).scanDirForPackage(0xc001898420, {{0xc004182665%3F, 0x81c8a92bb60e9ba5%3F}, 0x8%3F}, {0xc008108db0, 0x2c})
	  mod.go:727  0x705
golang.org/x/tools/internal/imports.(*ModuleResolver).scan.func3({{0xc004182665%3F, 0xdc5e20%3F}, 0xc0067f8f90%3F}, {0xc008108db0%3F, 0x17d12a8%3F})
	  mod.go:601  0x50
golang.org/x/tools/internal/gopathwalk.(*walker).walk(0xc0067b7830, {0xc0071f8100, 0x37}, 0x0, {0x1200af8, 0xc0071f0380})
	  walk.go:268  0x3d7
golang.org/x/tools/internal/gopathwalk.(*walker).walk(0xc0067b7830, {0xc004182665, 0x2c}, 0x0, {0x1200b30, 0xc0067f8f70})
	  walk.go:334  0x87b
golang.org/x/tools/internal/gopathwalk.walkDir({{0xc004182665%3F, 0xc0045a5f18%3F}, 0xc0045a5f18%3F}, 0xc0067f8f40, 0xc0067f8f30, {0x0%3F, 0x40%3F, 0x4%3F})
	  walk.go:120  0x366
golang.org/x/tools/internal/gopathwalk.WalkSkip(...)
	  walk.go:77
golang.org/x/tools/internal/imports.(*ModuleResolver).scan.func4()
	  mod.go:626  0x2db
created by golang.org/x/tools/internal/imports.(*ModuleResolver).scan in goroutine 4670
	  mod.go:610  0x465
gopls stats -anon { "DirStats": { "Files": 2035, "TestdataFiles": 0, "GoFiles": 1626, "ModFiles": 2, "Dirs": 528 }, "GOARCH": "amd64", "GOOS": "windows", "GOPACKAGESDRIVER": "", "GOPLSCACHE": "", "GoVersion": "go1.21.6", "GoplsVersion": "v0.15.3", "InitialWorkspaceLoadDuration": "7.6558984s", "MemStats": { "HeapAlloc": 31132976, "HeapInUse": 41328640, "TotalAlloc": 79278536 }, "WorkspaceStats": { "Files": { "Total": 2207, "Largest": 1654271, "Errs": 0 }, "Views": [ { "GoCommandVersion": "go1.21.6", "AllPackages": { "Packages": 417, "LargestPackage": 134, "CompiledGoFiles": 2217, "Modules": 49 }, "WorkspacePackages": { "Packages": 0, "LargestPackage": 0, "CompiledGoFiles": 0, "Modules": 0 }, "Diagnostics": 0 } ] } }

OPTIONAL: If you would like to share more information, you can attach your complete gopls logs.

NOTE: THESE MAY CONTAIN SENSITIVE INFORMATION ABOUT YOUR CODEBASE.
DO NOT SHARE LOGS IF YOU ARE WORKING IN A PRIVATE REPOSITORY.

<OPTIONAL: ATTACH LOGS HERE>

@Sangwaniya Sangwaniya changed the title gopls: automated issue report (crash) gopls: issue report (crash) May 3, 2024
@hyangah hyangah changed the title gopls: issue report (crash) gopls: crash during internal/imports.scanDirForPackage (crash) May 3, 2024
@hyangah hyangah changed the title gopls: crash during internal/imports.scanDirForPackage (crash) x/tools/gopls: crash during internal/imports.scanDirForPackage (crash) May 3, 2024
@hyangah hyangah transferred this issue from golang/vscode-go May 3, 2024
@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 May 3, 2024
@gopherbot gopherbot added this to the Unreleased milestone May 3, 2024
@hyangah
Copy link
Contributor

hyangah commented May 3, 2024

Thanks for the report @Sangwaniya
Transferring to the gopls issue tracker.

@hyangah hyangah modified the milestones: Unreleased, gopls/v0.15.4 May 3, 2024
@adonovan
Copy link
Member

adonovan commented May 3, 2024

Looks like root.Path has the same length as dir, but is not a prefix of it.

func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) directoryPackageInfo {
	subdir := ""
	if dir != root.Path {
		subdir = dir[len(root.Path)+len("/"):] // slice bounds out of range [45:44]
	}

@findleyr
Copy link
Contributor

Moving to the v0.17.0 milestone, since this seems to be affecting only one user (and in golang/vscode-go#3401 (comment), it appears that the cause may be related to a modified GOROOT).

@findleyr findleyr modified the milestones: gopls/v0.16.0, gopls/v0.17.0 May 29, 2024
@findleyr findleyr removed their assignment May 30, 2024
@Sangwaniya
Copy link
Author

hi @findleyr even after correcting the path and rebuilding gopls, still gopls is crashing
Here are the logs:
gopls version: v0.15.3/go1.21.6
gopls flags:
update flags: proxy
extension version: 0.41.4
environment: Visual Studio Code win32
initialization error: undefined
issue timestamp: Fri, 31 May 2024 05:05:47 GMT
restart history:
Fri, 31 May 2024 05:00:53 GMT: activation (enabled: true)

ATTENTION: PLEASE PROVIDE THE DETAILS REQUESTED BELOW.

Describe what you observed.

panic: runtime error: slice bounds out of range [45:44]

goroutine 1561 [running]:
golang.org/x/tools/internal/imports.(*ModuleResolver).scanDirForPackage(0xc00099c210, {{0xc000580de5%3F, 0x336f25b8b5a7258c%3F}, 0x8%3F}, {0xc0007dd1d0, 0x2c})
	  mod.go:727  0x705
golang.org/x/tools/internal/imports.(*ModuleResolver).scan.func3({{0xc000580de5%3F, 0x1215e20%3F}, 0xc000737ca0%3F}, {0xc0007dd1d0%3F, 0x1c212a8%3F})
	  mod.go:601  0x50
golang.org/x/tools/internal/gopathwalk.(*walker).walk(0xc000770cf0, {0xc000617a00, 0x37}, 0x0, {0x1650af8, 0xc0001bac40})
	  walk.go:268  0x3d7
golang.org/x/tools/internal/gopathwalk.(*walker).walk(0xc000770cf0, {0xc000580de5, 0x2c}, 0x0, {0x1650b30, 0xc000737c60})
	  walk.go:334  0x87b
golang.org/x/tools/internal/gopathwalk.walkDir({{0xc000580de5%3F, 0xc000bdff18%3F}, 0xc000bdff18%3F}, 0xc000737bf0, 0xc000737be0, {0x0%3F, 0x0%3F, 0x4%3F})
	  walk.go:120  0x366
golang.org/x/tools/internal/gopathwalk.WalkSkip(...)
	  walk.go:77
golang.org/x/tools/internal/imports.(*ModuleResolver).scan.func4()
	  mod.go:626  0x2db
created by golang.org/x/tools/internal/imports.(*ModuleResolver).scan in goroutine 226
	  mod.go:610  0x465
gopls stats -anon { "DirStats": { "Files": 2172, "TestdataFiles": 0, "GoFiles": 1626, "ModFiles": 2, "Dirs": 555 }, "GOARCH": "amd64", "GOOS": "windows", "GOPACKAGESDRIVER": "", "GOPLSCACHE": "", "GoVersion": "go1.21.6", "GoplsVersion": "v0.15.3", "InitialWorkspaceLoadDuration": "1.1454599s", "MemStats": { "HeapAlloc": 2580040, "HeapInUse": 5332992, "TotalAlloc": 36334560 }, "WorkspaceStats": { "Files": { "Total": 1, "Largest": 3429, "Errs": 0 }, "Views": [ { "GoCommandVersion": "go1.21.6", "AllPackages": { "Packages": 0, "LargestPackage": 0, "CompiledGoFiles": 0, "Modules": 0 }, "WorkspacePackages": { "Packages": 0, "LargestPackage": 0, "CompiledGoFiles": 0, "Modules": 0 }, "Diagnostics": 0 } ] } }

OPTIONAL: If you would like to share more information, you can attach your complete gopls logs.

NOTE: THESE MAY CONTAIN SENSITIVE INFORMATION ABOUT YOUR CODEBASE.
DO NOT SHARE LOGS IF YOU ARE WORKING IN A PRIVATE REPOSITORY.

<OPTIONAL: ATTACH LOGS HERE>

@hyangah
Copy link
Contributor

hyangah commented Jul 17, 2024

golang/vscode-go#3456 is another crash report. The report came from Linux. (@feldgendler by any chance, are you using a modified go, or GOROOT source?)

@feldgendler
Copy link

My Go comes from an official tarball, GOROOT is not set.

@feldgendler
Copy link

I tried adding debug prints just before the crash.

Just before the crashing subdir = dir[len(root.Path)+len("/"):] line,

root.Path is /home/alexey/onboard/legio/bin/../tools/deps/../../_deps/go@1.22.5/pkg/mod
dir is /home/alexey/onboard/legio/_deps/go@1.22.5/pkg/mod/mvdan.cc/gofumpt@v0.6.0

They just accidentally happen to have the same length.

@findleyr
Copy link
Contributor

Thanks @feldgendler, that's useful information that the paths are completely unrelated. That suggests the bug is elsewhere (in the code that expects scanned directories to be a subdirectory of the root...).

My first guess is that there's something related to symlinks, but we'll need to investigate.

@feldgendler
Copy link

In /home/alexey/onboard/legio/bin, I have a few symlinks like this: dlv -> ../tools/deps/trampoline.sh. None of the symlinks point to a directory, but some of them point ot a file under ../tools/deps, which might explain the /home/alexey/onboard/legio/bin/../tools/deps prefix. However, that deps directory doesn't contain any symlinks, just plain files.

Now, I'd very much like to help debugging this because this bug is making my IDE almost completely useless. I don't understand the idea behind the code here — what should it really do with symlinks? Does it need to resolve them at all?

@findleyr
Copy link
Contributor

Thanks, I will have more time to help investigate this later today.

In general, the philosophy around symlinks is:

  1. Don't rewrite paths: treat symlink paths like any other path, but...
  2. Keep track of symlinked directories to break cycles.

The code in question is very old, but has recently been modified to fix other bugs. It seems quite likely that some modification introduced a buggy handling of symlinks.

@feldgendler
Copy link

Thanks! Meanwhile, I tried replacing the crashing line with this:

	if s, ok := strings.CutPrefix(dir, root.Path+"/"); ok {
		subdir = s
	}

It seems to express the intent of the original line in a more robust way — assuming I understood it right.

This change seems to fix the issue for me — at least the scan now finishes without crashing.

@findleyr
Copy link
Contributor

@feldgendler yes, at a minimum we'll do something like that. Now that we have a someone reproducing the issue, it would be great if we could track down the root cause.

If you don't mind, later today or tomorrow I'm going to come up with a list of things for you to check, which will help us narrow this down. In the meantime, please use your patch to unblock your work.

@feldgendler
Copy link

Sure! Thanks a lot.

@findleyr
Copy link
Contributor

D'oh, I only just noticed that the scanned dir actually is a subdirectory of the root... if you clean the Root path.

Presumably you have a relative GOPATH, GOROOT, or replace directive, and that is being mishandled by goimports. I'm pretty confident that I can reproduce this -- peeking at the code indeed indicates that roots are not clean, and yet scanned directories are.

Thanks for taking the time to debug.

@findleyr findleyr self-assigned this Jul 26, 2024
@feldgendler
Copy link

Is there anything else I can do to help you here?

@findleyr
Copy link
Contributor

findleyr commented Aug 6, 2024

@feldgendler I've reproduced this crash in a test, and will send a fix shortly. If you could confirm that go env GOMODCACHE is unclean (includes /../), that would help me confirm that the context of my reproducer is accurate.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/603635 mentions this issue: internal/imports: use clean GOMODCACHE for the scan root directory

@Sangwaniya
Copy link
Author

@feldgendler yes correct

@feldgendler
Copy link

GOMODCACHE=/home/alexey/onboard/legio/bin/../tools/deps/../../_deps/go@1.22.5/pkg/mod

@feldgendler
Copy link

I just tested v0.16.2-pre.1, and the crash still happens.

@findleyr
Copy link
Contributor

findleyr commented Aug 19, 2024

@feldgendler indeed we have not yet cherry-picked the fix to a prerelease (we were actually just testing our new release automation when we cut -pre.1). We will fix in a -pre.2, thanks.

@feldgendler
Copy link

I'm not good at this syntax — is there a Go version expression I could use with go install to test the fix?

@findleyr
Copy link
Contributor

@feldgendler the best way to test the fix would be to install gopls@master, which you can do with the following command (we need to install from source as there is a replace directive in the gopls go.mod file during development).

git clone go.googlesource.com/tools
cd tools/gopls
go install

@feldgendler
Copy link

No crash when installed in this way, thank you!

@dottedmag
Copy link
Contributor

(we need to install from source as there is a replace directive in the gopls go.mod file during development)

Is this a leftover from before workspaces were added, or is there a reason to keep this replacement instead of go.work?

@findleyr
Copy link
Contributor

@dottedmag this is from before workspaces were added, but no we keep it because best practice is to not check in go.work files (see documentation here: https://go.dev/ref/mod#go-work-file).

In particular, while correctness requires that golang.org/x/tools/gopls imports the local golang.org/x/tools during development (because it uses the internals of x/tools), we want to support developers working on additional modules if they so choose. Checking in a go.work would circumvent that choice.

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

7 participants