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

cmd/go: 'go mod tidy -v' hangs and then segfaults with go1.12beta2 darwin/amd64 #30166

Closed
dmitris opened this issue Feb 11, 2019 · 11 comments

Comments

Projects
None yet
5 participants
@dmitris
Copy link
Contributor

commented Feb 11, 2019

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

$ go version
go version go1.12beta2 darwin/amd64

Does this issue reproduce with the latest release?

no

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

go env Output
$ go env
GOARCH="amd64"
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"

What did you do?

go mod tidy -v

What did you expect to see?

no error

What did you see instead?

go mod tidy hangs for very long time, then gives a stack overflow error: runtime: goroutine stack exceeds 1000000000-byte limit. Copy of error dump is attached.

gomodtidy-sefgault.txt

@thepudds thepudds added the modules label Feb 11, 2019

@dmitris

This comment has been minimized.

Copy link
Contributor Author

commented Feb 11, 2019

Was able to reproduce the go1.12beta2 hang / segfault on a different mac:
gohangs.txt
as well as on a linux VM - there it dies after go: extracting git.ouroath.com/mirror-github/gogo--protobuf v1.2.0:
gohangs-linux.txt

@dmitris

This comment has been minimized.

Copy link
Contributor Author

commented Feb 11, 2019

here's the time it takes to segfault on Linux:

real	1m54.256s
user	2m46.670s
sys	0m39.145s

On my Mac, go mod tidy now hangs for around 30min. - still at go: extracting git.ouroath.com/mirror-github/jmespath--go-jmespath v0.0.0-20180206000000-c2b33e8439af944379acbdd9c3a5fe0bc44bd8a5

@agnivade

This comment has been minimized.

Copy link
Member

commented Feb 11, 2019

Can you show us the repo where this crash is happening so that we can diagnose this issue faster ?

@dmitris

This comment has been minimized.

Copy link
Contributor Author

commented Feb 11, 2019

I wish I could - it is an internal project... I attach a slightly modified go.mod file, maybe it could help. I can reliably reproduce the crash - let me know if I can run some experiments etc. I'm building no the master version of go from the source and will try to see if the crash happens with the HEAD version as well. Can I save the state (cache directories - only ~/go/pkg?) to be able to restore the environment?

gomod.txt

@dmitris

This comment has been minimized.

Copy link
Contributor Author

commented Feb 11, 2019

was able to reproduce hang/crash with HEAD as well as go1.12beta1

@agnivade - I added a debugger to src/cmd/go/internal/modcmd/tidy.go in modTidyGoSum to print the values of m and r (Replacement) modules, and pass a recursive call depth counter (diff attached). I'm attaching a snippet of the output from running go mod tidy -v - call depth shows now 120776 after a couple of minutes runtime - seems like an infinite loop.

tidy.go.diff.txt
out-small.txt

@agnivade

This comment has been minimized.

Copy link
Member

commented Feb 11, 2019

/cc @bcmills

@dmitris

This comment has been minimized.

Copy link
Contributor Author

commented Feb 11, 2019

when I added a seen map to guard against reprocessing the module, the hanging stopped and go mod tidy returned quickly as usual (actually probably need to guard on the Path+Version combination)

+       var walk func(module.Version, int64)
+       seen := map[string]bool{}
+       walk = func(m module.Version, depth int64) {
+               if seen[m.Path] {
+                       fmt.Fprintf(os.Stderr, "DMDEBUG ALREADY seen module Path %s, Version %s - return, depth=%d\n", m.Path, m.Version, depth)
+                       return
+               }
+               seen[m.Path] = true
@bcmills

This comment has been minimized.

Copy link
Member

commented Feb 11, 2019

Thanks for the report. The bug is (sadly) pretty clear: we're storing the replaced directory in the keep map, but using the unreplaced path in the cycle check that uses it.

@bcmills

This comment has been minimized.

Copy link
Member

commented Feb 11, 2019

Here's a simple reproducer:


scratch$ mkdir -p ./cycle-a ./cycle-b

scratch$ cat >./cycle-a/a.go <<EOF
package a
EOF

scratch$ cat >./cycle-a/go.mod <<EOF
module golang.org/issue/cycle-a

go 1.12

require golang.org/issue/cycle-b v0.0.0
replace golang.org/issue/cycle-b => ./cycle-b
EOF

scratch$ cat >./main.go <<EOF
package main

import (
        _ "golang.org/issue/cycle-a"
        _ "golang.org/issue/cycle-b"
)
EOF

scratch$ cat >./go.mod <<EOF
module golang.org/issue/scratch

go 1.12

replace golang.org/issue/cycle-a => ./cycle-a

replace golang.org/issue/cycle-b => ./cycle-b

require (
        golang.org/issue/cycle-a v0.0.0
        golang.org/issue/cycle-b v0.0.0
)
EOF

scratch$ cat >./cycle-b/b.go <<EOF
package b
EOF

scratch$ cat >./cycle-b/go.mod <<EOF
module golang.org/issue/cycle-b

go 1.12

require golang.org/issue/cycle-a v0.0.0
replace golang.org/issue/cycle-a => ./cycle-a
EOF

scratch$ export GOTRACEBACK=none

scratch$ go mod tidy
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow

@gopherbot

This comment has been minimized.

Copy link

commented Feb 11, 2019

Change https://golang.org/cl/161917 mentions this issue: cmd/go/internal/modcmd: fix go mod tidy hangs

@gopherbot

This comment has been minimized.

Copy link

commented Feb 11, 2019

Change https://golang.org/cl/161898 mentions this issue: cmd/go/internal/modcmd: use replaced paths to break cycles in 'go mod tidy'

@bcmills bcmills added this to the Go1.12 milestone Feb 11, 2019

@gopherbot gopherbot closed this in 701f6a2 Feb 11, 2019

nebulabox added a commit to nebulabox/go that referenced this issue Feb 18, 2019

cmd/go/internal/modcmd: use replaced paths to break cycles in 'go mod…
… tidy'

Fixes golang#30166

Change-Id: I4704b57ed48197f512cd1b818e1f7d2fffc0d9ce
Reviewed-on: https://go-review.googlesource.com/c/161898
Run-TryBot: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

nebulabox added a commit to nebulabox/go that referenced this issue Feb 20, 2019

cmd/go/internal/modcmd: use replaced paths to break cycles in 'go mod…
… tidy'

Fixes golang#30166

Change-Id: I4704b57ed48197f512cd1b818e1f7d2fffc0d9ce
Reviewed-on: https://go-review.googlesource.com/c/161898
Run-TryBot: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.