-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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: race-like removal of first line by codeAction #35114
Comments
Thanks for reporting. Does |
No we do not Apologies, I meant to link to the entire https://gist.github.com/myitcv/f8d3bd52e3a31c30b2befe7909eae285 I'm not sure this can be diff related though can it? Because it doesn't fail every time, only 1 in 5 times (roughly). Hence my assumption this is a race-like error? |
Do you have any sense of which CL caused this to become an issue? It does sound like a race, but the behavior here is very strange. My best guess is that there is some sort of race where it tries to do Also, why is the [Trace - 20:58:48.415 PM] Sending notification 'textDocument/didChange'.
Params: {"textDocument":{"version":1,"uri":"file:///tmp/go-test-script389776774/script-format_on_save_new_file/main.go"},"contentChanges":[{"range":{"start":{"line":1,"character":0},"end":{"line":1,"character":0}},"text":"package main\n\nfunc main() {\n}\n"}]}
[Trace - 20:58:48.416 PM] Sending notification 'textDocument/didChange'.
Params: {"textDocument":{"version":2,"uri":"file:///tmp/go-test-script389776774/script-format_on_save_new_file/main.go"},"contentChanges":[{"range":{"start":{"line":0,"character":0},"end":{"line":1,"character":0}},"text":""}]} |
Ooh, I had totally missed this, good spot. The second of those changes sent by
This is actually a programming error in the But here's the interesting thing: pre this fix both So this I think reveals quite a nasty race bug somewhere in |
Does passing for this test mean that the code remained unchanged? Or that the code action responds with the expected edits? There may be a weird interaction here with the |
The situation is somewhat complicated by the fact there is an error in the
package main
func main() {
}
and
Hence
But this then breaks the test from
which is how we were alerted to this
So I think the question is, why does |
Ok, some further analysis, which invalidates much of what is above. TL;DR version
The scenario we have is actually as follows:
package main
func main() {
} This leaves the Vim buffer with the following, note the first blank line:
package main
func main() {
} The test then adjusts for this to remove the first blank line, meaning the buffer is in the following state: package main
func main() {
}
Note the first change references LSP line 1. So the net effect of these two changes leaves package main
func main() {
} This is confirmed with some rudimentary logging in
This change is then relayed to But this then breaks the test from
which is how we were alerted to this
So I think the question are:
Because in both cases (test passing or failing) it always sees the same changes from |
Thanks for the logs. Took a look at them, but nothing stands out yet. I put up a very basic CL with some additional logging as a starting point (see https://golang.org/cl/204457). It would be helpful to know what the imports code action thinks it is doing in this case. I think that this bug might be a good application for @pjweinb's work on replaying |
To summarize some offline discussion - there seem to be 2 errors here. The first is the "no parsed files" error for the "passing" case. The second is the modification of the file in the racey case. I am able to reproduce the first scenario with the log replayer, so I will focus on debugging it first. It also seems like the cause of the race is |
Change https://golang.org/cl/204557 mentions this issue: |
Updates golang/go#30843 Updates golang/go#35114 Change-Id: Id3f66d20b1ada9e53298b2370214b23b87bb0680 Reviewed-on: https://go-review.googlesource.com/c/tools/+/204557 Run-TryBot: Rebecca Stambler <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Cottrell <[email protected]>
Change https://golang.org/cl/204457 mentions this issue: |
We are seeing another instance of the error:
when calling Separately, assuming that the error is indeed an error, this returns us to the question of whether Why do we swallow these errors in Unless there is some way that we determine that a file has parse errors and hence avoid the formatting/codeAction call on save? |
Further update, with
|
That panic appears to have been introduced in https://go-review.googlesource.com/c/tools/+/204822 |
cc @matloob |
Change https://golang.org/cl/206160 mentions this issue: |
I've managed to make a bit of progress on this by comparing the
Just as a refresher (more details in the comments above):
package main
func main() {
} Then the first line is removed (state C): package main
func main() {
} Then we run codeAction, then (assuming no error from the previous step) we run Formatting.
This does not appear to be correct, because if we create a file in state C then open Vim we do not see this error in the
AnalysisIn https://go-review.googlesource.com/c/tools/+/206160 I've pushed up some backtrace logging to help with debugging. Here are two In the "passing" test the sequence of backtrace logs are, at a high level, as follows:
Notice the interleaving of the diagnostic runs between the content updates. This results in codeAction returning The failing sequence of backtrace logs are, at a high level, as follows:
Notice the additional invalidation of content as part of the codeAction call. Rough conclusions
|
The panic you're seeing looks like #35468. I'll send a fix for that soon. |
With the recent versioned text document changes (https://go-review.googlesource.com/c/tools/+/206882 and https://go-review.googlesource.com/c/tools/+/205863) we're still seeing this issue and now more explicitly so in the same test:
|
We are blocked on updating to the latest commit of tools/gopls because of issues related to golang/go#35114. Hence we update as far as we can. * internal/telemetry: make test event with functions 95cb2a1a * internal/lsp: change annotation tests to json 023c5eea * go/packages/packagestest: add package use example 77e3bb0a * lsp/protocol/typescript: add instructions for typescript compiling b2a5ed32 * internal/lsp: look up files in packages by position instead of URI bc1376d6 * internal/lsp: use versioned URIs in rename and code actions e33b02e7 * internal/memoize: propagate cancellation 76a3b8da * internal/lsp/source: unify import adding code c81e7ae8 * gopls/doc: expand Emacs docs aa38f8e9 This PR also cherry picks a later commit from CL 207344 which is maintained on a soft fork for now. Also includes a number of required govim changes: * switch to using DocumentChanges on a WorkspaceEdit for formats, renames and suggested fixes * as part of the previous change, verify that the versioned edits we are apply correspond to the current version of a buffer * fix up some bad logging in the gopls logging server wrapper * start buffer/watched file version numbers at 1 in order to free up version 0 for any special "apply regardless" semantics * add a test that verifies the behaviour of gopls when creating a new file in a pre-existing package (i.e. another file already exists in the package)
We are blocked on updating to the latest commit of tools/gopls because of issues related to golang/go#35114. Hence we update as far as we can. * internal/telemetry: make test event with functions 95cb2a1a * internal/lsp: change annotation tests to json 023c5eea * go/packages/packagestest: add package use example 77e3bb0a * lsp/protocol/typescript: add instructions for typescript compiling b2a5ed32 * internal/lsp: look up files in packages by position instead of URI bc1376d6 * internal/lsp: use versioned URIs in rename and code actions e33b02e7 * internal/memoize: propagate cancellation 76a3b8da * internal/lsp/source: unify import adding code c81e7ae8 * gopls/doc: expand Emacs docs aa38f8e9 This PR also cherry picks a later commit from CL 207344 which is maintained on a soft fork for now. Also includes a number of required govim changes: * switch to using DocumentChanges on a WorkspaceEdit for formats, renames and suggested fixes * as part of the previous change, verify that the versioned edits we are apply correspond to the current version of a buffer * fix up some bad logging in the gopls logging server wrapper * start buffer/watched file version numbers at 1 in order to free up version 0 for any special "apply regardless" semantics * add a test that verifies the behaviour of gopls when creating a new file in a pre-existing package (i.e. another file already exists in the package)
We are blocked on updating to the latest commit of tools/gopls because of issues related to golang/go#35114. Hence we update as far as we can. * internal/telemetry: make test event with functions 95cb2a1a * internal/lsp: change annotation tests to json 023c5eea * go/packages/packagestest: add package use example 77e3bb0a * lsp/protocol/typescript: add instructions for typescript compiling b2a5ed32 * internal/lsp: look up files in packages by position instead of URI bc1376d6 * internal/lsp: use versioned URIs in rename and code actions e33b02e7 * internal/memoize: propagate cancellation 76a3b8da * internal/lsp/source: unify import adding code c81e7ae8 * gopls/doc: expand Emacs docs aa38f8e9 This PR also cherry picks a later commit from CL 207344 which is maintained on a soft fork for now. Also includes a number of required govim changes: * switch to using DocumentChanges on a WorkspaceEdit for formats, renames and suggested fixes * as part of the previous change, verify that the versioned edits we are apply correspond to the current version of a buffer * fix up some bad logging in the gopls logging server wrapper * start buffer/watched file version numbers at 1 in order to free up version 0 for any special "apply regardless" semantics * add a test that verifies the behaviour of gopls when creating a new file in a pre-existing package (i.e. another file already exists in the package)
@myitcv: I tried to reproduce this and failed. I checked out govim, changed the replace statements to point to my local copy of x/tools, commented out the skip in format_on_save_new_file.txt, and ran |
I spent some time staring at the logs in #35114 (comment) and I'm quite confused. In the passing log, the code action never replied, so how can we know the test passed? And in the failing log, there is a code action reply, but it's empty, so why did it fail? |
Because as explained in #35694 we are forced to ignore errors returned by either
Quoting the comment you linked to:
The test again runs to completion, but in the case of |
Ah. Sorry, I missed the formatting reply, was too fixated on codeAction because of the issue title. And now I see the Error for request 2 in the passing log. Okay, I'm starting to put the pieces together. Here's my understanding, sorry to keep making you repeat yourself. Overlays: An overlay is, by definition, a diff between gopls' state and the state on disk. We don't currently implement The Then we come to the bad formatting, which I think has to be a separate issue. On the one hand, the fact that you're getting edits for the wrong snapshot version is somewhat reassuring, since it means things aren't going totally haywire. On the other hand, I don't know why it's working off the old snapshot. I'll stare for a while. |
The other thing is that I think I really need a new set of log files to make any progress. |
Indeed, which is why we make a separate
I'll work on this. One of the other critical issues preventing us from moving forward to a later |
FWIW we're still seeing this in 95cb2a1 (with 80313e1 and 61fa4df cherry-picked on top): https://travis-ci.org/govim/govim/jobs/621836927?utm_medium=notification&utm_source=github_status This failure is part of the PR I've pushed up as a test: https://travis-ci.org/govim/govim/builds/621836926?utm_source=github_status&utm_medium=notification At the time of writing, 4 failures during the race test section. This is hard to test against the latest |
@stamblerre @heschik
Agreed. This issue is now too old to be useful. As I mention above, we've been stuck between a bit of a rock and a hard place because upgrading to the latest But in govim/govim#584 we've narrowed that
@stamblerre is working on both so I think we're close. So my plan is to close this issue and re-open/create new issues as necessary once we're "green" on govim/govim#584. Thanks for you help looking into this in any case. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
In
govim
we have a test that effectively "pastes" the following contents into a new, unsaved buffer calledmain.go
(hence does not exist on disk) and then saves the file:In the test however we sometimes see the first line, the package clause, being removed by the codeAction that fires on save. Here is the relevant line from the
gopls
log:What did you expect to see?
The file contents preserved by the codeAction.
What did you see instead?
The package clause being removed 1 time in 5 this test runs.
cc @stamblerre
The text was updated successfully, but these errors were encountered: