-
Notifications
You must be signed in to change notification settings - Fork 5k
The method returns inconsistent expected results after running it about 10,000 times #108811
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
Comments
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
Before the bug appears, the codeaddr of the method is
After the bug appears, the codeaddr of the method is
|
@EgorBo PTAL. |
Cc @dotnet/jit-contrib . |
@czd890 what is |
Ah, I was able to repro. Seems like the issue is .NET8.0 specific. Does not repro on .NET9.0 or Main (.NET10). So we should probably find the fix and backport it. |
@jakobbotsch The company has strict version control and many projects need to be updated. Upgrading to net9 is not a good option at the moment.😢 |
Hi @EgorBo Would you mind sharing why this bug is triggered? |
A codegen bug related to exception handling fixed by #95945 as Jakob found out. @BruceForstall can we backport your change (#95945) to 8.0? |
It's not realistic to backport that change; it's too large. There were also a number of related follow-up changes. This change in itself should not have caused any correctness changes, so I'm surprised that it is pinpointed as a fix to a problem. |
Hi @BruceForstall @EgorBo have any updates for this? |
This issue has been marked |
Ah, oops, missed it. The repro is the same as is attached to the issue description, I only slightly reduced it and validated that it was fixed in .NET 9.0 and then Jakob (with his collection of coreruns) confirmed that the issue was fixed by #95945 using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
public class Program
{
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public static void Main()
{
var hex = "3AE46205A50ED00E7612A91692552B7A";
var key = "abcdef1234567890";
var iv = "abcdef1234567890";
var bytes = Convert.FromHexString(hex);
for (int i = 0; i < 200; i++)
{
var result = new Program().Decrypt(bytes, key, iv, out _);
if (result == 1)
throw new Exception("Bug!");
Console.WriteLine(result);
Thread.Sleep(10);
}
}
public int Decrypt(byte[] buffer, string key, string iv, out byte[] decryptedData)
{
int decryptedByteCount = 0;
decryptedData = new byte[buffer.Length];
using var aes = Aes.Create();
aes.Mode = CipherMode.CBC;
aes.KeySize = 128;
aes.Padding = PaddingMode.Zeros;
z
var instPwdArray = Encoding.ASCII.GetBytes(key);
var instSaltArray = Encoding.ASCII.GetBytes(iv);
using (var decryptor = aes.CreateDecryptor(instPwdArray, instSaltArray))
{
using (var memoryStream = new MemoryStream(buffer))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
int read;
do
{
read = cryptoStream.Read(
decryptedData,
decryptedByteCount,
decryptedData.Length - decryptedByteCount);
decryptedByteCount += read;
} while (read != 0);
}
}
}
// Found the accurate length of decrypted data
while (decryptedData[decryptedByteCount - 1] == 0 && decryptedByteCount > 0)
decryptedByteCount--;
return decryptedByteCount;
}
} (Run on Windows-x64, .NET 8.0, default settings, so TC=1 - it will throw an exception). |
I just checked again -- on d2cbd1c this results in
after tiering. On 8725a6e, it produces "9" forever. |
Ok, thanks. Looks like the bug is that we think a callfinally pair tail is a viable loop preheader, and we hoist some code there, which is a no-no. Seems like there might be a surgical fix. |
I think the fix is simply: --- a/src/coreclr/jit/optimizer.cpp
+++ b/src/coreclr/jit/optimizer.cpp
@@ -1801,7 +1801,7 @@ private:
//
BasicBlock* FindEntry(BasicBlock* head, BasicBlock* top, BasicBlock* bottom)
{
- if (head->bbJumpKind == BBJ_ALWAYS)
+ if ((head->bbJumpKind == BBJ_ALWAYS) && !head->isBBCallAlwaysPairTail())
{
if (head->bbJumpDest->bbNum <= bottom->bbNum && head->bbJumpDest->bbNum >= top->bbNum)
{ In .NET 9 all this was redone; we no longer find loops this way and we no longer have BBJ_ALWAYS pair tails. |
A loop preheader can't be a callfinally pair tail. Fixes dotnet#108811.
* JIT: Fix loop recognition bug in .NET 8 A loop preheader can't be a callfinally pair tail. Fixes #108811. * exclude new test from wasm
This should be fixed in 8.0.16, coming soon.... |
Hi @AndyAyersMS, Very happy to hear this good news, I will close this issue. |
Uh oh!
There was an error while loading. Please reload this page.
Description
I use fixed parameters to loop the test. After running about 10,000 times, the returned decryptedByteCount will change from 9 to 1. This happens widely on multiple net8 versions of Linux and Windows.
the code should use release to build. If it is debug mode, this bug cannot be reproduced.
Does this seem to be related to the JIT not optimizing correctly?
test parameters
If I modify the code to the following two methods, this problem can be fixed.
method1: using(){} struct for aes
method2: add MemoryBarrier.
Reproduction Steps
Repeat the run more than 10,000 times.
Expected behavior
The results should always be consistent.
Actual behavior
After running it about 10,000 times, it will always return wrong results.
Regression?
has never happened on net6.
Known Workarounds
No response
Configuration
No response
Other information
No response
The text was updated successfully, but these errors were encountered: