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

fix for race condition in FileIndex.fileIndexOfFile #18008

Merged
merged 19 commits into from
Dec 10, 2024

Conversation

Martin521
Copy link
Contributor

@Martin521 Martin521 commented Nov 15, 2024

Description

Here is a fix for another ancient bug that I found while working on "scoped nowarn".
It took a while to find the culprit.
There is a race condition in FileIndex.fileIndexOfFile that can lead to different indices for the same file.
This PR contains the fix and a regression test.

@Martin521 Martin521 requested a review from a team as a code owner November 15, 2024 14:36
Copy link
Contributor

github-actions bot commented Nov 15, 2024

❗ Release notes required


✅ Found changes and release notes in following paths:

Change path Release notes path Description
src/Compiler docs/release-notes/.FSharp.Compiler.Service/9.0.200.md

@Martin521
Copy link
Contributor Author

Can somebody add the "No release notes" label? Thanks!

@psfinaki
Copy link
Member

Actually you can probably add them - it's a bug fix, it's notable from the product perspective :)

(as opposed to refactoring or adding tests - they could be very useful but don't compose a new "release" really).

@Martin521
Copy link
Contributor Author

That makes sense. I have added them.

BTW the change is small, hopefully easy to review.

@psfinaki
Copy link
Member

Thanks for the contribution, Martin. The change is indeed small, but anything that touches critical parts of the compiler needs a focused review :)

We're a bit busy with .NET9 handling and some internal stuff right now, we hope to get to the PRs soon - thanks for your patience!

@Martin521
Copy link
Contributor Author

Some remarks that might help in reviewing this PR:

  • The issue is for real
    • I observed, in a "sometimes" failing "scoped nowarn" test, that FileToIndex sometimes returns different file indices for the same file name.
    • The test added in this PR reproduces this for the current compiler.
  • The only thing that the fix does is to lock the whole read-check-write operation rather than just the write operations. I think it should be clear that the read-check-write must be an atomic operation.
  • FileToIndex is called just once per compiled file (plus once per #line directive). So, there should be no performance impact. If there is still concern, we can add an unlocked read-check before the locked operations, so that the lock is entered only for new files. But I don't think it is worth it.

@psfinaki
Copy link
Member

/azp run

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@Martin521
Copy link
Contributor Author

ILVerify succeeds locally for this same commit

@psfinaki
Copy link
Member

psfinaki commented Dec 9, 2024

I think I have something similar happening in my PR, it's very annoying indeed.

@vzarytovskii
Copy link
Member

vzarytovskii commented Dec 9, 2024

ILVerify succeeds locally for this same commit

It is indeed failing in this branch locally for me:

> git log -1
commit d4a64bd1a4ba1f21741ce922f8562c8a48b09521 (HEAD -> fileindex-race, Martin521/fileindex-race)
Merge: f1abc28b4 9ab4e3935
Author: Petr <psfinaki@users.noreply.github.com>
Date:   Mon Dec 9 15:42:57 2024 +0100

    Merge branch 'main' into fileindex-race
    
> pwsh tests/ILVerify/ilverify.ps1
pwsh tests/ILVerify/ilverify.ps1
Checking whether running on Windows: False
Repository path: /Users/u/code/fsharp4
...


InputObject
-----------                                                                                                                                                                                                                                                                                                                                                             
[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1423-11::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<FSharp.Compiler.Syntax.SyntaxNode>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1<FSharp.Compiler.EditorServices.CompletionContext>…
[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1423-11::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<FSharp.Compiler.Syntax.SyntaxNode>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1<FSharp.Compiler.EditorServices.CompletionContext>…

ILverify output matches baseline.
ILverify failed.

> git diff
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
index cd2141db4..9de22b5cd 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
@@ -33,7 +33,7 @@
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x0000002B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseEntity@218::GenerateNext([S.P.CoreLib]System.Collections.Generic.IEnumerable`1<FSharp.Compiler.EditorServices.AssemblySymbol>&)][offset 0x000000BB][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1423-11::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<FSharp.Compiler.Syntax.SyntaxNode>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1<FSharp.Compiler.EditorServices.CompletionContext>>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1<FSharp.Compiler.EditorServices.CompletionContext>>, [FSharp.Compiler.Service]FSharp.Compiler.Syntax.SynExpr)][offset 0x00000618][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1423-11::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<FSharp.Compiler.Syntax.SyntaxNode>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1<FSharp.Compiler.EditorServices.CompletionContext>>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1<FSharp.Compiler.EditorServices.CompletionContext>>, [FSharp.Compiler.Service]FSharp.Compiler.Syntax.SynExpr)][offset 0x00000620][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-523::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-523::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-523::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack.

ILVerify will always need to run on an up-to-date proto and product compilers, because it always does a clean build in the CI, but not locally if not built from clean state.

So git clean -xdf && pwsh tests/ILVerify/ilverify.ps1 should always do it.

Meanwhile, I've pushed baseline changes.

@Martin521
Copy link
Contributor Author

Hah, it's green now. Thank you @vzarytovskii.

@psfinaki
Copy link
Member

Alright, getting this in. Thanks Martin for dealing with annoying edge cases / races.

@psfinaki psfinaki merged commit f105888 into dotnet:main Dec 10, 2024
33 checks passed
psfinaki added a commit that referenced this pull request Dec 12, 2024
* Backport :: Bugfix :: Support `ldelem.u8`, `ldelem.u` opcode aliases (#18081) (#18096)

* Streamlining test deps a bit (#18022)

* Streamlining test deps a bit

* up

* Format ILVerify output a bit (#18120)

* fix for race condition in FileIndex.fileIndexOfFile (#18008)

* fix for race condition in FileIndex.fileIndexOfFile

* fantomas

* fixed ilverify baselines (just a single line number changed)

* add release notes entry

* FileToIndex: Added unlocked read so that lock is entered for new files only

* update ilverify baselines (changed line numbers only)

* Fix ILVerify

---------

Co-authored-by: Petr <psfinaki@users.noreply.github.com>
Co-authored-by: Vlad Zarytovskii <vzaritovsky@hotmail.com>

* Update F# build version to 200

* Fix how much is trimmed from an interp string part (#18123)

* Fix how much is trimmed from an interp string part

Only trim last 2 characters if they are "%s" and the '%' is not escaped

* Add release note

---------

Co-authored-by: Adam Boniecki <abonie@users.noreply.github.com>

* Sink: report SynPat.ArrayOrList type (#18127)

---------

Co-authored-by: Tomas Grosup <tomasgrosup@microsoft.com>
Co-authored-by: Petr <psfinaki@users.noreply.github.com>
Co-authored-by: Martin <29605222+Martin521@users.noreply.github.com>
Co-authored-by: Vlad Zarytovskii <vzaritovsky@hotmail.com>
Co-authored-by: Adam Boniecki <20281641+abonie@users.noreply.github.com>
Co-authored-by: Adam Boniecki <abonie@users.noreply.github.com>
Co-authored-by: Alex Berezhnykh <alexey.berezhnykh@jetbrains.com>
Co-authored-by: Kevin Ransom (msft) <codecutter@hotmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

5 participants