Repository navigation
Sporadic failure in file enumeration tests on Unix #54589
Copy link
Copy link
Closed
Labels
area-System.IOblocking-clean-ciBlocking PR or rolling runs of 'runtime' or 'runtime-extra-platforms'Blocking PR or rolling runs of 'runtime' or 'runtime-extra-platforms'bug
Milestone
Description
Examples - -
System.IO.Tests.DirectoryInfo_EnumFSI_str_str.SearchPatternCaseSensitive [FAIL]
System.UnauthorizedAccessException : Access to the path '/tmp/DirectoryInfo_EnumFSI_str_str_i42flluh.s3p/SearchPatternCaseSensitive_705_652a74c1' is denied.
---- System.IO.IOException : Bad file descriptor
Stack Trace:
/_/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs(197,0): at System.IO.Enumeration.FileSystemEnumerator`1.FindNextEntry(Byte* entryBufferPtr, Int32 bufferLength)
/_/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs(110,0): at System.IO.Enumeration.FileSystemEnumerator`1.MoveNext()
/_/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs(27,0): at System.Linq.Enumerable.SelectEnumerableIterator`2.ToArray()
/_/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/EnumerableAPIs.cs(73,0): at System.IO.Tests.DirectoryInfo_EnumFSI_str_str.GetEntries(String path, String searchPattern)
/_/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str.cs(719,0): at System.IO.Tests.Directory_GetFileSystemEntries_str_str.SearchPatternCaseSensitive()
----- Inner Stack Trace -----
System.IO.Tests.DirectoryInfo_EnumerateFiles_str_str.PatternTests_DosDotTrailingDot(pattern: "foo.*", sourceFiles: ["foo", "foo.", "foo.t", "foo.tx", "foo.txt", ...], expected: ["foo", "foo.", "foo.t", "foo.tx", "foo.txt", ...]) [FAIL]
System.UnauthorizedAccessException : Access to the path '/var/folders/fs/wj3by_p90wq589rz5xk5ltb40000gy/T/DirectoryInfo_EnumerateFiles_str_str_mmyqz5al.lod/PrepareDirectory_539_23baf34f' is denied.
---- System.IO.IOException : Bad file descriptor
Stack Trace:
/_/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs(178,0): at System.IO.Enumeration.FileSystemEnumerator`1.FindNextEntry(Byte* entryBufferPtr, Int32 bufferLength)
/_/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs(93,0): at System.IO.Enumeration.FileSystemEnumerator`1.MoveNext()
/_/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs(27,0): at System.Linq.Enumerable.SelectEnumerableIterator`2.ToArray()
/_/src/libraries/System.Linq/src/System/Linq/ToCollection.cs(11,0): at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
/_/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/EnumerableAPIs.cs(28,0): at System.IO.Tests.DirectoryInfo_EnumerateFiles_str_str.GetEntries(String path, String searchPattern)
/_/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str.cs(343,0): at System.IO.Tests.Directory_GetFileSystemEntries_str_str.PatternTests_DosDotTrailingDot(String pattern, String[] sourceFiles, String[] expected)
----- Inner Stack Trace -----
Some other callstack variations:
at System.IO.Strategies.FileStreamHelpers.CheckFileCall(Int64 result, String path, Boolean ignoreNotSupported) in /_/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/FileStreamHelpers.Unix.cs:line 29
at System.IO.Strategies.Net5CompatFileStreamStrategy.CheckFileCall(Int32 result, Boolean ignoreNotSupported) in /_/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/Net5CompatFileStreamStrategy.Unix.cs:line 624
at System.IO.Strategies.Net5CompatFileStreamStrategy.WriteNative(ReadOnlySpan`1 source) in /_/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/Net5CompatFileStreamStrategy.Unix.cs:line 457
at System.IO.Strategies.Net5CompatFileStreamStrategy.FlushWriteBuffer(Boolean calledFromFinalizer) in /_/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/Net5CompatFileStreamStrategy.Unix.cs:line 189
at System.IO.Strategies.Net5CompatFileStreamStrategy.Dispose(Boolean disposing) in /_/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/Net5CompatFileStreamStrategy.Unix.cs:line 93
at System.IO.Strategies.Net5CompatFileStreamStrategy.DisposeInternal(Boolean disposing) in /_/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/Net5CompatFileStreamStrategy.cs:line 110
at System.IO.FileStream.Dispose(Boolean disposing) in /_/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs:line 476
at System.IO.Stream.Close() in /_/src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs:line 165
at System.IO.StreamWriter.CloseStreamFromDispose(Boolean disposing) in /_/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs:line 235
at System.IO.StreamWriter.Dispose(Boolean disposing) in /_/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs:line 218
at System.IO.TextWriter.Dispose() in /_/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs:line 77
at System.IO.File.WriteAllText(String path, String contents) in /_/src/libraries/System.Private.CoreLib/src/System/IO/File.cs:line 312
at System.IO.Tests.Directory_GetFileSystemEntries_str.CreateItem(String path) in /_/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str.cs:line 28
at System.IO.Tests.Directory_GetFileSystemEntries_str_str.PrepareDirectory(String[] sourceFiles, Boolean useExtendedPaths) in /_/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str.cs:line 542
at System.IO.Tests.Directory_GetFileSystemEntries_str_str.PatternTests_DosDotTrailingDot(String pattern, String[] sourceFiles, String[] expected) in /_/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str.cs:line 342
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) in /_/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.cs:line 370
----- Inner Stack Trace -----
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode) in /_/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs:line 91
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize) in /_/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs:line 158
at System.IO.Strategies.Net5CompatFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize) in /_/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/Net5CompatFileStreamStrategy.cs:line 92
at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize) in /_/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/FileStreamHelpers.Unix.cs:line 16
at System.IO.Strategies.FileStreamHelpers.ChooseStrategy(FileStream fileStream, String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize) in /_/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/FileStreamHelpers.cs:line 20
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize) in /_/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs:line 210
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) in /_/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs:line 146
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync) in /_/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs:line 141
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize) in /_/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs:line 136
at System.IO.StreamWriter.ValidateArgsAndOpenPath(String path, Boolean append, Encoding encoding, Int32 bufferSize) in /_/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs:line 182
at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize) in /_/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs:line 153
at System.IO.StreamWriter..ctor(String path) in /_/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs:line 138
at System.IO.File.WriteAllText(String path, String contents) in /_/src/libraries/System.Private.CoreLib/src/System/IO/File.cs:line 309
at System.IO.Tests.Directory_GetFileSystemEntries_str.CreateItem(String path) in /_/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str.cs:line 28
at System.IO.Tests.Directory_GetFileSystemEntries_str_str.PrepareDirectory(String[] sourceFiles, Boolean useExtendedPaths) in /_/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str.cs:line 542
at System.IO.Tests.Directory_GetFileSystemEntries_str_str.PatternTests_DosDotTrailingDot(String pattern, String[] sourceFiles, String[] expected) in /_/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str.cs:line 342
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) in /_/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.cs:line 370
----- Inner Stack Trace -----
This began failing a few times a day on 6/15 which is coincident with #53669. Perhaps this will be fixed by #54483 @adamsitnik
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area-System.IOblocking-clean-ciBlocking PR or rolling runs of 'runtime' or 'runtime-extra-platforms'Blocking PR or rolling runs of 'runtime' or 'runtime-extra-platforms'bug
Activity
danmoseley commentedon Jun 23, 2021
Doh - that's a Windows change, still the date these started seems to be 2021-06-15 21:36:40.9310000
https://engsrvprod.kusto.windows.net/engineeringdata?query=H4sIAAAAAAAEAG2QQWsCMRCF74L%2fYdiLLay6emthC7YiWKjQKvQo02Tqxt2dSGYWEfzxTdT2VAhMMvky771sSPSDpGtUoN87w947htqxLR0zBfj0oV4qtQKe%2fw5L%2by%2f76r8uWKxLm4BjRYFg4dhJRRaeSrCopK6lu2kxLYbFw3ACxWOR1n2%2fh2xhczoQiGJQOTqtIFufJCqOVqSj7Iq8kVbeQllC9uKjsNHtnGW77owhkRt0zZSgwQJdM%2bj3xuPrYxHcERjPio4FshkDapQ4KBxRoEVLoB40IItTF%2fMgKEqdmgjfjrFJBpVSPAanUKEFbAKhPcW57aEhJZvcnuEQ%2fD4ahHVKRDaHeRcwDc1vMXJ476ijFbY0yX%2fd5Yk39SagiftZ2HUtsUq8R1M5vtA5PEeHpsovX%2fYDIyPQ4McBAAA%3d&web=0
TestResults
| join kind=inner WorkItems on WorkItemId
| join kind=inner Jobs on JobId
| where Finished >= datetime(2020-09-1 0:00:00)
and Type startswith "System.Net."
and Method == "Connect_Dns_Success"
and Result == 'Fail'
//and Message contains "An attempt was made to transition a task to a final state when it had already completed."
| project Started, Duration, Method, QueueName1, Message, StackTrace, Arguments, MachineName, Branch, Type
adamsitnik commentedon Jun 23, 2021
The issue seems to be very mysterious. Let's consider following example:
The source code:
runtime/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
Lines 43 to 74 in 0416c34
What happens:
SafeFileHandleis being created. The result is stored in a local variable, which is not shared with anyone else. (line 43)FStatusing the handle and it fails. (line 71)Bad file descriptor. Descriptor can be bad when it's closed. But how is it possible that it got closed since it has not been shared with anyone yet? (line 74)My current reaction:

danmoseley commentedon Jun 23, 2021
Brainstorming - are there other possible causes of EBADF? Eg., file is locked by someone using a different fd?
@tmds
tmds commentedon Jun 23, 2021
A thought about the code @adamsitnik shared:
We should call
GetLastErrorInfobefore callingDispose, otherwiseDisposemight change the error.I'll look at the issue closer in the coming week.
jkotas commentedon Jun 24, 2021
The easiest explanation is that some other thread closed the file descriptor in the meantime. File descriptors are small numbers, and get reused heavily. This is a potential sequence of events:
Thread A: calls close
Thread B: calls open - returns same fd as Thread A just closed
Thread A: calls close second time (bug!). It closes fd that Thread B is holding to now.
Thread B: calls lstat and gets EBADF
This failure pattern is consistent with what happened in #54615. The code called
pipesyscall and immediately got EBADF trying to operate on the pipe file descriptors.So I would be looking for a buggy code that is calling close twice.
danmoseley commentedon Jun 24, 2021
Oh of course. Hmm, interesting, as just about everything uses SafeXHandle, so it should be hard to call close() twice.
More info from Kusto: first hit is 2021-06-15 21:36:40.9310000 (I assume it's UTC) after which it happens fairly often so I'd guess that's within a few hours of the problem being introduced. 9d771a2 went in at Tue Jun 15 20:59:58 2021 +0200.
It happens in both release and debug. It only happens when running System.IO.Tests.* - which is consistent with the bug being in the tests, but not conclusive. It hits mostly tests that enumerate files, perhaps because there's a lot of fd's involved. The biggest hitter is System.IO.Tests.DirectoryInfo_EnumerateFiles_str_str but there are many others.
It's evenly distributed across distros and macOS, but of course never Windows. Both x64 and Arm.
danmoseley commentedon Jun 24, 2021
Is this problematic?
runtime/src/libraries/System.IO.FileSystem/tests/RandomAccess/Base.cs
Lines 44 to 53 in 9d771a2
The SafeFileHandle takes ownership of the raw pipe handle. it is disposed and closes it, then the pipe is disposed and closes it again. This was introduce by above change.
Fix sporadic double fd close
Fix sporadic double fd close (#54660)
adamsitnik commentedon Jun 24, 2021
@danmoseley @tmds @jkotas big thanks for your help!!
With #54660 I can't reproduce it anymore.
I've opened #54667 to address that
Fix sporadic double fd close (#54660)