runtime: SequenceEqual broken for concurrent use?
Repro:
using System;
using System.Security.Cryptography;
using System.Threading;
class Program
{
static void Main()
{
static void Work(object _)
{
while (true)
{
Span<byte> buffer1 = RandomNumberGenerator.GetBytes(1024 * 1024);
Span<byte> buffer2 = new byte[buffer1.Length];
buffer1.CopyTo(buffer2);
if (!buffer1.SequenceEqual(buffer2)) // should never be false...
{
while (!buffer1.SequenceEqual(buffer2)) ; // but if it is, it certainly shouldn't go back to true...
throw new Exception("What in the world just happened?!");
}
}
}
ThreadPool.QueueUserWorkItem(Work);
ThreadPool.QueueUserWorkItem(Work);
Console.ReadLine();
}
}
This runs without error on .NET 5.
On master on my Windows machine (I’ve not tried other OSes), within a few seconds I get a failure like this:
Unhandled exception. System.Exception: SequenceEquals changed from false to true?!
at Program.Work() in C:\Users\stoub\source\repos\ConsoleApp17\ConsoleApp17\Program.cs:line 25
at Program.<>c.<Main>b__0_0(Object _) in C:\Users\stoub\source\repos\ConsoleApp17\ConsoleApp17\Program.cs:line 10
at System.Threading.QueueUserWorkItemCallbackDefaultContext.Execute() in D:\repos\runtime\src\libraries\System.Private.CoreLib\src\System\Threading\ThreadPool.cs:line 977
at System.Threading.ThreadPoolWorkQueue.Dispatch() in D:\repos\runtime\src\libraries\System.Private.CoreLib\src\System\Threading\ThreadPool.cs:line 705
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart() in D:\repos\runtime\src\libraries\System.Private.CoreLib\src\System\Threading\PortableThreadPool.WorkerThread.cs:line 56
at System.Threading.Thread.StartCallback() in D:\repos\runtime\src\coreclr\System.Private.CoreLib\src\System\Threading\Thread.CoreCLR.cs:line 105
Note that if I remove one of the ThreadPool calls so that there’s no concurrency, it’s never failed for me; only once I introduce the parallelism does it start to fail.
JIT bug? GC? Some kind of latent issue in SequenceEquals?
cc: @geoffkizer, @jkotas
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 44 (43 by maintainers)
I think any CLR version that supports AVX intrinsics and still receives servicing fixes may need to get this fix at some point.
New issue would be better for servicing. I will create one for 5.0, and can keep that around for more down-level ports if required
I do not think anybody is working on it. It would great if you can pick it up. Thank you!
I think it got triggered by memcpy changes in CRT. Are you on VS dogfood or have you installed VS update recently?
memcpy - shipping .NET 5.0 bits:
memcpy - master compiled using latest VS dogfood (Version 16.9.0 Preview 4.0 [30914.28.main])
I am still unable to repro. Likely requires newest C runtime/compiler.
Looks like https://github.com/dotnet/runtime/issues/38974 finally caught up with us.
You may need to be on latest VS dogfood to see the crash and/or have processor without the ERMSB feature.
Here is what’s happening:
SpanHelpers.SequenceEqual:memcpyat:memcpyis optimized using AVX that modifies ymm0 register as side-effect:Seconds on my machine, using src from master this afternoon.
This looks like a thread suspension bug to me. @VSadov Could you please take a look since you have done refactoring of that code recently?