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: deadlock opening many files at once #32910

Closed
muirdm opened this issue Jul 2, 2019 · 2 comments
Closed

x/tools/gopls: deadlock opening many files at once #32910

muirdm opened this issue Jul 2, 2019 · 2 comments
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls.
Milestone

Comments

@muirdm
Copy link

muirdm commented Jul 2, 2019

While testing a different issue I ran into a new deadlock. I think it boils down to a different lock acquisition order in these two code paths:

Path 1:

  1. loadParseTypecheck acquires mcache mutex
  2. eventually gets into lsp/cache.(*fileBase).Handle which acquires f.handleMu

Path 2:

  1. lsp/cache.(*goFile).invalidateContent acquires f.handleMu and then tries acquiring mcache mutex.

Here is the full goroutine trace:

goroutine profile: total 100
91 @ 0x1030c0f 0x10078aa 0x1007880 0x100756b 0x131ad28 0x105d841
#	0x131ad27	golang.org/x/tools/internal/jsonrpc2.(*Conn).Run.func1+0x37	/Users/muir/projects/tools/internal/jsonrpc2/jsonrpc2.go:429

1 @ 0x1030c0f 0x10078aa 0x1007880 0x100756b 0x1525c69 0x1525968 0x138755a 0x1388d99 0x1367907 0x15269bc 0x15269ab 0x1525f40 0x1525968 0x138755a 0x1388d99 0x1367907 0x15269bc 0x15269ab 0x1525f40 0x105d841
#	0x1525c68	golang.org/x/tools/internal/lsp/cache.(*importer).getPkg+0x1a8		/Users/muir/projects/tools/internal/lsp/cache/check.go:59
#	0x1525967	golang.org/x/tools/internal/lsp/cache.(*importer).Import+0x87		/Users/muir/projects/tools/internal/lsp/cache/check.go:41
#	0x1387559	go/types.(*Checker).importPackage+0x6e9					/usr/local/go/src/go/types/resolver.go:161
#	0x1388d98	go/types.(*Checker).collectObjects+0x15f8				/usr/local/go/src/go/types/resolver.go:256
#	0x1367906	go/types.(*Checker).checkFiles+0x96					/usr/local/go/src/go/types/check.go:252
#	0x15269bb	go/types.(*Checker).Files+0x9db						/usr/local/go/src/go/types/check.go:245
#	0x15269aa	golang.org/x/tools/internal/lsp/cache.(*importer).typeCheck+0x9ca	/Users/muir/projects/tools/internal/lsp/cache/check.go:187
#	0x1525f3f	golang.org/x/tools/internal/lsp/cache.(*importer).getPkg+0x47f		/Users/muir/projects/tools/internal/lsp/cache/check.go:68
#	0x1525967	golang.org/x/tools/internal/lsp/cache.(*importer).Import+0x87		/Users/muir/projects/tools/internal/lsp/cache/check.go:41
#	0x1387559	go/types.(*Checker).importPackage+0x6e9					/usr/local/go/src/go/types/resolver.go:161
#	0x1388d98	go/types.(*Checker).collectObjects+0x15f8				/usr/local/go/src/go/types/resolver.go:256
#	0x1367906	go/types.(*Checker).checkFiles+0x96					/usr/local/go/src/go/types/check.go:252
#	0x15269bb	go/types.(*Checker).Files+0x9db						/usr/local/go/src/go/types/check.go:245
#	0x15269aa	golang.org/x/tools/internal/lsp/cache.(*importer).typeCheck+0x9ca	/Users/muir/projects/tools/internal/lsp/cache/check.go:187
#	0x1525f3f	golang.org/x/tools/internal/lsp/cache.(*importer).getPkg+0x47f		/Users/muir/projects/tools/internal/lsp/cache/check.go:68

1 @ 0x1030c0f 0x10078aa 0x1007880 0x100756b 0x1525c69 0x1525968 0x138755a 0x1388d99 0x1367907 0x15269bc 0x15269ab 0x1525f40 0x152acd5 0x1529983 0x1529cac 0x152a2f4 0x14c85be 0x1517a38 0x1523677 0x105d841
#	0x1525c68	golang.org/x/tools/internal/lsp/cache.(*importer).getPkg+0x1a8			/Users/muir/projects/tools/internal/lsp/cache/check.go:59
#	0x1525967	golang.org/x/tools/internal/lsp/cache.(*importer).Import+0x87			/Users/muir/projects/tools/internal/lsp/cache/check.go:41
#	0x1387559	go/types.(*Checker).importPackage+0x6e9						/usr/local/go/src/go/types/resolver.go:161
#	0x1388d98	go/types.(*Checker).collectObjects+0x15f8					/usr/local/go/src/go/types/resolver.go:256
#	0x1367906	go/types.(*Checker).checkFiles+0x96						/usr/local/go/src/go/types/check.go:252
#	0x15269bb	go/types.(*Checker).Files+0x9db							/usr/local/go/src/go/types/check.go:245
#	0x15269aa	golang.org/x/tools/internal/lsp/cache.(*importer).typeCheck+0x9ca		/Users/muir/projects/tools/internal/lsp/cache/check.go:187
#	0x1525f3f	golang.org/x/tools/internal/lsp/cache.(*importer).getPkg+0x47f			/Users/muir/projects/tools/internal/lsp/cache/check.go:68
#	0x152acd4	golang.org/x/tools/internal/lsp/cache.(*view).loadParseTypecheck+0x1e4		/Users/muir/projects/tools/internal/lsp/cache/load.go:49
#	0x1529982	golang.org/x/tools/internal/lsp/cache.(*goFile).GetPackages+0x322		/Users/muir/projects/tools/internal/lsp/cache/gofile.go:112
#	0x1529cab	golang.org/x/tools/internal/lsp/cache.(*goFile).GetPackage+0x4b			/Users/muir/projects/tools/internal/lsp/cache/gofile.go:137
#	0x152a2f3	golang.org/x/tools/internal/lsp/cache.(*goFile).GetActiveReverseDeps+0x73	/Users/muir/projects/tools/internal/lsp/cache/gofile.go:198
#	0x14c85bd	golang.org/x/tools/internal/lsp/source.Diagnostics+0x2ad			/Users/muir/projects/tools/internal/lsp/source/diagnostics.go:88
#	0x1517a37	golang.org/x/tools/internal/lsp.(*Server).Diagnostics+0x267			/Users/muir/projects/tools/internal/lsp/diagnostics.go:27
#	0x1523676	golang.org/x/tools/internal/lsp.(*Server).didOpen.func1+0x66			/Users/muir/projects/tools/internal/lsp/text_synchronization.go:29

1 @ 0x1030c0f 0x102c3da 0x102b9c6 0x10bb88b 0x10bdeca 0x10bdeab 0x114bee2 0x1166b52 0x1165728 0x12e78fd 0x1512856 0x1512803 0x105d841
#	0x102b9c5	internal/poll.runtime_pollWait+0x55			/usr/local/go/src/runtime/netpoll.go:182
#	0x10bb88a	internal/poll.(*pollDesc).wait+0x9a			/usr/local/go/src/internal/poll/fd_poll_runtime.go:87
#	0x10bdec9	internal/poll.(*pollDesc).waitRead+0x1b9		/usr/local/go/src/internal/poll/fd_poll_runtime.go:92
#	0x10bdeaa	internal/poll.(*FD).Accept+0x19a			/usr/local/go/src/internal/poll/fd_unix.go:384
#	0x114bee1	net.(*netFD).accept+0x41				/usr/local/go/src/net/fd_unix.go:238
#	0x1166b51	net.(*TCPListener).accept+0x31				/usr/local/go/src/net/tcpsock_posix.go:139
#	0x1165727	net.(*TCPListener).Accept+0x47				/usr/local/go/src/net/tcpsock.go:260
#	0x12e78fc	net/http.(*Server).Serve+0x22c				/usr/local/go/src/net/http/server.go:2859
#	0x1512855	net/http.Serve+0x4c5					/usr/local/go/src/net/http/server.go:2456
#	0x1512802	golang.org/x/tools/internal/lsp/debug.Serve.func1+0x472	/Users/muir/projects/tools/internal/lsp/debug/serve.go:232

1 @ 0x1030c0f 0x1040f89 0x1040f5f 0x1040cfd 0x1073419 0x1528b22 0x1526dad 0x1525f40 0x1525968 0x138755a 0x1388d99 0x1367907 0x15269bc 0x15269ab 0x1525f40 0x1525968 0x138755a 0x1388d99 0x1367907 0x15269bc 0x15269ab 0x1525f40 0x105d841
#	0x1040cfc	sync.runtime_SemacquireMutex+0x3c					/usr/local/go/src/runtime/sema.go:71
#	0x1073418	sync.(*Mutex).Lock+0x108						/usr/local/go/src/sync/mutex.go:134
#	0x1528b21	golang.org/x/tools/internal/lsp/cache.(*fileBase).Handle+0x41		/Users/muir/projects/tools/internal/lsp/cache/file.go:60
#	0x1526dac	golang.org/x/tools/internal/lsp/cache.(*importer).typeCheck+0xdcc	/Users/muir/projects/tools/internal/lsp/cache/check.go:126
#	0x1525f3f	golang.org/x/tools/internal/lsp/cache.(*importer).getPkg+0x47f		/Users/muir/projects/tools/internal/lsp/cache/check.go:68
#	0x1525967	golang.org/x/tools/internal/lsp/cache.(*importer).Import+0x87		/Users/muir/projects/tools/internal/lsp/cache/check.go:41
#	0x1387559	go/types.(*Checker).importPackage+0x6e9					/usr/local/go/src/go/types/resolver.go:161
#	0x1388d98	go/types.(*Checker).collectObjects+0x15f8				/usr/local/go/src/go/types/resolver.go:256
#	0x1367906	go/types.(*Checker).checkFiles+0x96					/usr/local/go/src/go/types/check.go:252
#	0x15269bb	go/types.(*Checker).Files+0x9db						/usr/local/go/src/go/types/check.go:245
#	0x15269aa	golang.org/x/tools/internal/lsp/cache.(*importer).typeCheck+0x9ca	/Users/muir/projects/tools/internal/lsp/cache/check.go:187
#	0x1525f3f	golang.org/x/tools/internal/lsp/cache.(*importer).getPkg+0x47f		/Users/muir/projects/tools/internal/lsp/cache/check.go:68
#	0x1525967	golang.org/x/tools/internal/lsp/cache.(*importer).Import+0x87		/Users/muir/projects/tools/internal/lsp/cache/check.go:41
#	0x1387559	go/types.(*Checker).importPackage+0x6e9					/usr/local/go/src/go/types/resolver.go:161
#	0x1388d98	go/types.(*Checker).collectObjects+0x15f8				/usr/local/go/src/go/types/resolver.go:256
#	0x1367906	go/types.(*Checker).checkFiles+0x96					/usr/local/go/src/go/types/check.go:252
#	0x15269bb	go/types.(*Checker).Files+0x9db						/usr/local/go/src/go/types/check.go:245
#	0x15269aa	golang.org/x/tools/internal/lsp/cache.(*importer).typeCheck+0x9ca	/Users/muir/projects/tools/internal/lsp/cache/check.go:187
#	0x1525f3f	golang.org/x/tools/internal/lsp/cache.(*importer).getPkg+0x47f		/Users/muir/projects/tools/internal/lsp/cache/check.go:68

1 @ 0x1030c0f 0x1040f89 0x1040f5f 0x1040cfd 0x1073419 0x15296c4 0x1529cac 0x152a2f4 0x14c85be 0x1517a38 0x1523677 0x105d841
#	0x1040cfc	sync.runtime_SemacquireMutex+0x3c						/usr/local/go/src/runtime/sema.go:71
#	0x1073418	sync.(*Mutex).Lock+0x108							/usr/local/go/src/sync/mutex.go:134
#	0x15296c3	golang.org/x/tools/internal/lsp/cache.(*goFile).GetPackages+0x63		/Users/muir/projects/tools/internal/lsp/cache/gofile.go:108
#	0x1529cab	golang.org/x/tools/internal/lsp/cache.(*goFile).GetPackage+0x4b			/Users/muir/projects/tools/internal/lsp/cache/gofile.go:137
#	0x152a2f3	golang.org/x/tools/internal/lsp/cache.(*goFile).GetActiveReverseDeps+0x73	/Users/muir/projects/tools/internal/lsp/cache/gofile.go:198
#	0x14c85bd	golang.org/x/tools/internal/lsp/source.Diagnostics+0x2ad			/Users/muir/projects/tools/internal/lsp/source/diagnostics.go:88
#	0x1517a37	golang.org/x/tools/internal/lsp.(*Server).Diagnostics+0x267			/Users/muir/projects/tools/internal/lsp/diagnostics.go:27
#	0x1523676	golang.org/x/tools/internal/lsp.(*Server).didOpen.func1+0x66			/Users/muir/projects/tools/internal/lsp/text_synchronization.go:29

1 @ 0x1030c0f 0x1040f89 0x1040f5f 0x1040cfd 0x1073419 0x153371f 0x153615e 0x1535116 0x1535cd0 0x153158a 0x1530a2e 0x1521630 0x151ea39 0x13265c4 0x131ae07 0x105d841
#	0x1040cfc	sync.runtime_SemacquireMutex+0x3c					/usr/local/go/src/runtime/sema.go:71
#	0x1073418	sync.(*Mutex).Lock+0x108						/usr/local/go/src/sync/mutex.go:134
#	0x153371e	golang.org/x/tools/internal/lsp/cache.(*goFile).invalidateContent+0x7e	/Users/muir/projects/tools/internal/lsp/cache/view.go:231
#	0x153615d	golang.org/x/tools/internal/lsp/cache.(*view).getFile.func1+0x4d	/Users/muir/projects/tools/internal/lsp/cache/view.go:354
#	0x1535115	golang.org/x/tools/internal/lsp/cache.(*WatchMap).Notify+0xd5		/Users/muir/projects/tools/internal/lsp/cache/watcher.go:54
#	0x1535ccf	golang.org/x/tools/internal/lsp/cache.(*session).openOverlay.func1+0x6f	/Users/muir/projects/tools/internal/lsp/cache/session.go:267
#	0x1531589	golang.org/x/tools/internal/lsp/cache.(*session).openOverlay+0x389	/Users/muir/projects/tools/internal/lsp/cache/session.go:283
#	0x1530a2d	golang.org/x/tools/internal/lsp/cache.(*session).DidOpen+0xfd		/Users/muir/projects/tools/internal/lsp/cache/session.go:191
#	0x152162f	golang.org/x/tools/internal/lsp.(*Server).didOpen+0xcf			/Users/muir/projects/tools/internal/lsp/text_synchronization.go:23
#	0x151ea38	golang.org/x/tools/internal/lsp.(*Server).DidOpen+0x48			/Users/muir/projects/tools/internal/lsp/server.go:138
#	0x13265c3	golang.org/x/tools/internal/lsp/protocol.serverHandler.func1+0x20c3	/Users/muir/projects/tools/internal/lsp/protocol/tsserver.go:104
#	0x131ae06	golang.org/x/tools/internal/jsonrpc2.(*Conn).Run.func1+0x116		/Users/muir/projects/tools/internal/jsonrpc2/jsonrpc2.go:441

1 @ 0x104c81e 0x10a5637 0x10bc62f 0x10bc609 0x10c2020 0x10c1ff3 0x11cf69f 0x11d03ed 0x11d0890 0x13197d9 0x13197cb 0x1318c92 0x15426a1 0x154267b 0x1539f87 0x1538dd3 0x153c5bc 0x1539f87 0x1538dd3 0x154ba9a 0x103081c 0x105d841
#	0x104c81d	syscall.syscall+0x2d						/usr/local/go/src/runtime/sys_darwin.go:63
#	0x10a5636	syscall.read+0x66						/usr/local/go/src/syscall/zsyscall_darwin_amd64.go:1169
#	0x10bc62e	syscall.Read+0x12e						/usr/local/go/src/syscall/syscall_unix.go:172
#	0x10bc608	internal/poll.(*FD).Read+0x108					/usr/local/go/src/internal/poll/fd_unix.go:165
#	0x10c201f	os.(*File).read+0x6f						/usr/local/go/src/os/file_unix.go:263
#	0x10c1ff2	os.(*File).Read+0x42						/usr/local/go/src/os/file.go:108
#	0x11cf69e	bufio.(*Reader).fill+0x10e					/usr/local/go/src/bufio/bufio.go:100
#	0x11d03ec	bufio.(*Reader).ReadSlice+0x3c					/usr/local/go/src/bufio/bufio.go:356
#	0x11d088f	bufio.(*Reader).ReadBytes+0x6f					/usr/local/go/src/bufio/bufio.go:434
#	0x13197d8	bufio.(*Reader).ReadString+0x98					/usr/local/go/src/bufio/bufio.go:474
#	0x13197ca	golang.org/x/tools/internal/jsonrpc2.(*headerStream).Read+0x8a	/Users/muir/projects/tools/internal/jsonrpc2/stream.go:97
#	0x1318c91	golang.org/x/tools/internal/jsonrpc2.(*Conn).Run+0xa1		/Users/muir/projects/tools/internal/jsonrpc2/jsonrpc2.go:396
#	0x15426a0	golang.org/x/tools/internal/lsp.(*Server).Run+0x540		/Users/muir/projects/tools/internal/lsp/server.go:61
#	0x154267a	golang.org/x/tools/internal/lsp/cmd.(*Serve).Run+0x51a		/Users/muir/projects/tools/internal/lsp/cmd/serve.go:95
#	0x1539f86	golang.org/x/tools/internal/tool.Main.func2+0xb6		/Users/muir/projects/tools/internal/tool/tool.go:130
#	0x1538dd2	golang.org/x/tools/internal/tool.Main+0x242			/Users/muir/projects/tools/internal/tool/tool.go:131
#	0x153c5bb	golang.org/x/tools/internal/lsp/cmd.(*Application).Run+0x4ab	/Users/muir/projects/tools/internal/lsp/cmd/cmd.go:106
#	0x1539f86	golang.org/x/tools/internal/tool.Main.func2+0xb6		/Users/muir/projects/tools/internal/tool/tool.go:130
#	0x1538dd2	golang.org/x/tools/internal/tool.Main+0x242			/Users/muir/projects/tools/internal/tool/tool.go:131
#	0x154ba99	main.main+0x119							/Users/muir/projects/tools/cmd/gopls/main.go:22
#	0x103081b	runtime.main+0x20b						/usr/local/go/src/runtime/proc.go:200

1 @ 0x104c81e 0x10a5637 0x10bc62f 0x10bc609 0x114b5cf 0x115db39 0x12dd378 0x105d841
#	0x104c81d	syscall.syscall+0x2d				/usr/local/go/src/runtime/sys_darwin.go:63
#	0x10a5636	syscall.read+0x66				/usr/local/go/src/syscall/zsyscall_darwin_amd64.go:1169
#	0x10bc62e	syscall.Read+0x12e				/usr/local/go/src/syscall/syscall_unix.go:172
#	0x10bc608	internal/poll.(*FD).Read+0x108			/usr/local/go/src/internal/poll/fd_unix.go:165
#	0x114b5ce	net.(*netFD).Read+0x4e				/usr/local/go/src/net/fd_unix.go:202
#	0x115db38	net.(*conn).Read+0x68				/usr/local/go/src/net/net.go:177
#	0x12dd377	net/http.(*connReader).backgroundRead+0x57	/usr/local/go/src/net/http/server.go:677

1 @ 0x1505550 0x1505370 0x1501f40 0x150ece6 0x150f747 0x12e4244 0x12e6146 0x12e7518 0x12e3201 0x105d841
#	0x150554f	runtime/pprof.writeRuntimeProfile+0x8f	/usr/local/go/src/runtime/pprof/pprof.go:708
#	0x150536f	runtime/pprof.writeGoroutine+0x9f	/usr/local/go/src/runtime/pprof/pprof.go:670
#	0x1501f3f	runtime/pprof.(*Profile).WriteTo+0x38f	/usr/local/go/src/runtime/pprof/pprof.go:329
#	0x150ece5	net/http/pprof.handler.ServeHTTP+0x355	/usr/local/go/src/net/http/pprof/pprof.go:245
#	0x150f746	net/http/pprof.Index+0x6f6		/usr/local/go/src/net/http/pprof/pprof.go:268
#	0x12e4243	net/http.HandlerFunc.ServeHTTP+0x43	/usr/local/go/src/net/http/server.go:1995
#	0x12e6145	net/http.(*ServeMux).ServeHTTP+0x1d5	/usr/local/go/src/net/http/server.go:2375
#	0x12e7517	net/http.serverHandler.ServeHTTP+0xa7	/usr/local/go/src/net/http/server.go:2774
#	0x12e3200	net/http.(*conn).serve+0x850		/usr/local/go/src/net/http/server.go:1878

/cc @stamblerre

@gopherbot gopherbot added this to the Unreleased milestone Jul 2, 2019
@gopherbot gopherbot added the gopls Issues related to the Go language server, gopls. label Jul 2, 2019
@muirdm
Copy link
Author

muirdm commented Jul 3, 2019

@ianthehat while testing out a fix for above deadlock I hit a different deadlock involving the watcher. Basically one codepath tries adding a file to the watcher while holding the view's mutex, and another codepath is invoking a watcher callback (which holds the watcher mutex) and the callback acquires the view mutex. I have annotated the relevant stack traces below with @@mutex.

Do you think we should make the watcher not hold the mutex while invoking the callbacks (i.e. copy the slice of callbacks before invoking), or perhaps invoke the callbacks in a goroutine (or something else)?

          1 @ 0x1030c0f 0x1040f89 0x1040f5f 0x1040cfd 0x1073419 0x1532dac 0x153582e 0x15347e6 0x15353a0 0x1530c5a 0x15300fe 0x1520d30 0x151e139 0x13265c4 0x131ae07 0x105d841
          #	0x1040cfc	sync.runtime_SemacquireMutex+0x3c					/usr/local/go/src/runtime/sema.go:71
          #	0x1073418	sync.(*Mutex).Lock+0x108						/usr/local/go/src/sync/mutex.go:134
@@view    #	0x1532dab	golang.org/x/tools/internal/lsp/cache.(*goFile).invalidateContent+0x3b	/Users/muir/projects/tools/internal/lsp/cache/view.go:230
          #	0x153582d	golang.org/x/tools/internal/lsp/cache.(*view).getFile.func1+0x4d	/Users/muir/projects/tools/internal/lsp/cache/view.go:356
@@watcher #	0x15347e5	golang.org/x/tools/internal/lsp/cache.(*WatchMap).Notify+0xd5		/Users/muir/projects/tools/internal/lsp/cache/watcher.go:54
          #	0x153539f	golang.org/x/tools/internal/lsp/cache.(*session).openOverlay.func1+0x6f	/Users/muir/projects/tools/internal/lsp/cache/session.go:267
          #	0x1530c59	golang.org/x/tools/internal/lsp/cache.(*session).openOverlay+0x389	/Users/muir/projects/tools/internal/lsp/cache/session.go:283
          #	0x15300fd	golang.org/x/tools/internal/lsp/cache.(*session).DidOpen+0xfd		/Users/muir/projects/tools/internal/lsp/cache/session.go:191
          #	0x1520d2f	golang.org/x/tools/internal/lsp.(*Server).didOpen+0xcf			/Users/muir/projects/tools/internal/lsp/text_synchronization.go:23
          #	0x151e138	golang.org/x/tools/internal/lsp.(*Server).DidOpen+0x48			/Users/muir/projects/tools/internal/lsp/server.go:138
          #	0x13265c3	golang.org/x/tools/internal/lsp/protocol.serverHandler.func1+0x20c3	/Users/muir/projects/tools/internal/lsp/protocol/tsserver.go:104
          #	0x131ae06	golang.org/x/tools/internal/jsonrpc2.(*Conn).Run.func1+0x116		/Users/muir/projects/tools/internal/jsonrpc2/jsonrpc2.go:441

          1 @ 0x1030c0f 0x1040f89 0x1040f5f 0x1040cfd 0x1073419 0x153448e 0x1533aca 0x152bb3d 0x152af68 0x152a2b5 0x1529053 0x152937c 0x14c7a76 0x1517138 0x1522d47 0x105d841
          #	0x1040cfc	sync.runtime_SemacquireMutex+0x3c					/usr/local/go/src/runtime/sema.go:71
          #	0x1073418	sync.(*Mutex).Lock+0x108						/usr/local/go/src/sync/mutex.go:134
@@watcher #	0x153448d	golang.org/x/tools/internal/lsp/cache.(*WatchMap).Watch+0x4d		/Users/muir/projects/tools/internal/lsp/cache/watcher.go:26
          #	0x1533ac9	golang.org/x/tools/internal/lsp/cache.(*view).getFile+0x229		/Users/muir/projects/tools/internal/lsp/cache/view.go:351
          #	0x152bb3c	golang.org/x/tools/internal/lsp/cache.(*view).link+0x19c		/Users/muir/projects/tools/internal/lsp/cache/load.go:217
          #	0x152af67	golang.org/x/tools/internal/lsp/cache.(*view).checkMetadata+0x487	/Users/muir/projects/tools/internal/lsp/cache/load.go:109
@@mcache  #	0x152a2b4	golang.org/x/tools/internal/lsp/cache.(*view).loadParseTypecheck+0xf4	/Users/muir/projects/tools/internal/lsp/cache/load.go:29
@@view    #	0x1529052	golang.org/x/tools/internal/lsp/cache.(*goFile).GetPackages+0x322	/Users/muir/projects/tools/internal/lsp/cache/gofile.go:112
          #	0x152937b	golang.org/x/tools/internal/lsp/cache.(*goFile).GetPackage+0x4b		/Users/muir/projects/tools/internal/lsp/cache/gofile.go:137
          #	0x14c7a75	golang.org/x/tools/internal/lsp/source.Diagnostics+0x65			/Users/muir/projects/tools/internal/lsp/source/diagnostics.go:62
          #	0x1517137	golang.org/x/tools/internal/lsp.(*Server).Diagnostics+0x267		/Users/muir/projects/tools/internal/lsp/diagnostics.go:27
          #	0x1522d46	golang.org/x/tools/internal/lsp.(*Server).didOpen.func1+0x66		/Users/muir/projects/tools/internal/lsp/text_synchronization.go:29

@gopherbot
Copy link

Change https://golang.org/cl/184880 mentions this issue: internal/lsp: fix deadlocks loading lots of files at once

movie-travel-code pushed a commit to movie-travel-code/tools that referenced this issue Jul 11, 2019
The first deadlock involved differing mutex acquisition order in two
code paths:

1. loadParseTypecheck() holds the "mcache" mutex then eventually
   acquires the "handleMu" file mutex.
2. (*goFile).invalidateContent() acquires the "handleMu" mutex first and
   then the "mcache" mutex.

Fix by changing the acquisition order in invalidateContent().

The second deadlock involved the file watcher. The two code paths
involved were:

1. (*goFile).GetPackages() holds the view mutex and eventually calls
   (*WatchMap).Watch, which acquires the watcher mutex.
2. (*session).openOverlay acquires the watcher mutex as it triggers a
   file's callbacks, and then the callback
   "(*goFile).invalidateContent" acquires the view mutex.

Fix by not holding the watcher mutex as we invoke the callbacks.

Fixes golang/go#32910

Change-Id: I9d060e0d80fd86a317a1d6c7aaa736a8ce10bd07
GitHub-Last-Rev: 04944fa
GitHub-Pull-Request: golang#129
Reviewed-on: https://go-review.googlesource.com/c/tools/+/184880
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
@golang golang locked and limited conversation to collaborators Jul 2, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants