Skip to content

Commit ec543c5

Browse files
adonovangopherbot
authored andcommitted
gopls/internal/lsp/cache: fix crash in Session.updateViewLocked
The createView release function should not be called until we have finished using the view's overlays. Change-Id: I988c7f5e8fa8bc41108b491286501881b03a535f Reviewed-on: https://go-review.googlesource.com/c/tools/+/496884 Reviewed-by: Robert Findley <[email protected]> Auto-Submit: Alan Donovan <[email protected]> Run-TryBot: Alan Donovan <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent a12ee94 commit ec543c5

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

gopls/internal/lsp/cache/session.go

+11-9
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,14 @@ func (s *Session) NewView(ctx context.Context, name string, folder span.URI, opt
109109

110110
// TODO(rfindley): clarify that createView can never be cancelled (with the
111111
// possible exception of server shutdown).
112+
// On success, the caller becomes responsible for calling the release function once.
112113
func (s *Session) createView(ctx context.Context, name string, folder span.URI, options *source.Options, seqID uint64) (*View, *snapshot, func(), error) {
113114
index := atomic.AddInt64(&viewIndex, 1)
114115

115116
// Get immutable workspace information.
116117
info, err := s.getWorkspaceInformation(ctx, folder, options)
117118
if err != nil {
118-
return nil, nil, func() {}, err
119+
return nil, nil, nil, err
119120
}
120121

121122
gowork, _ := info.GOWORK()
@@ -327,6 +328,15 @@ func (s *Session) updateViewLocked(ctx context.Context, view *View, options *sou
327328
}
328329

329330
v, snapshot, release, err := s.createView(ctx, view.name, view.folder, options, seqID)
331+
if err != nil {
332+
// we have dropped the old view, but could not create the new one
333+
// this should not happen and is very bad, but we still need to clean
334+
// up the view array if it happens
335+
s.views = removeElement(s.views, i)
336+
return nil, err
337+
}
338+
defer release()
339+
330340
// The new snapshot has lost the history of the previous view. As a result,
331341
// it may not see open files that aren't in its build configuration (as it
332342
// would have done via didOpen notifications). This can lead to inconsistent
@@ -336,15 +346,7 @@ func (s *Session) updateViewLocked(ctx context.Context, view *View, options *sou
336346
for _, o := range v.fs.Overlays() {
337347
_, _ = snapshot.ReadFile(ctx, o.URI())
338348
}
339-
release()
340349

341-
if err != nil {
342-
// we have dropped the old view, but could not create the new one
343-
// this should not happen and is very bad, but we still need to clean
344-
// up the view array if it happens
345-
s.views = removeElement(s.views, i)
346-
return nil, err
347-
}
348350
// substitute the new view into the array where the old view was
349351
s.views[i] = v
350352
return v, nil

0 commit comments

Comments
 (0)