-
Notifications
You must be signed in to change notification settings - Fork 4.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
AccessViolationException in MicroBenchmarks.Serializers.Json_FromString<MyEventsListerViewModel>.Jil_ benchmark #64657
Comments
Tagging subscribers to this area: @JulieLeeMSFT Issue DetailsWhen running the dotnet/performance benchmarks with 7.0 preview 1 bits on my mac M1 ARM64 device, I've found that the ldr wzr, [x3, w1, uxtw #2] The I have captured the disassembly of the method with embedded IL here: https://gist.github.com/janvorli/643f0e3b3acacb083af3178b5a232bc2 The crash happens at 00000002842f832c. The The whole string is this one:
I believe this is the source code at the failure point (the Read method seems to be inlined): Here is the stack trace of the exception:
Unfortunately, the runtime was a release build, so I couldn't get a JIT dump. However, the benchmark scripts allow to use a self-built runtime, so it should not be difficult to get it repro even with a checked build of the runtime. Here are the repro steps:
The test run takes quite some time, but it always crashes at that place for me.
|
cc @dotnet/jit-contrib |
cc: @adamsitnik - this is the issue I have mentioned to you. |
I'll take a look, looks like an incorrect scaling mode for implicit nullchecks |
@janvorli thanks for the detailed analysis!! it seems it's a general bug in JIT and not arm64 specific. Basically the same as #59315 (comment) (thanks to @jakobbotsch for pointing to this) Repro: using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
public unsafe class Prog
{
[DllImport("kernel32")]
public static extern byte* VirtualAlloc(IntPtr lpAddress, nuint dwSize, uint flAllocationType, uint flProtect);
[MethodImpl(MethodImplOptions.NoInlining)]
static void Validate(char* c, int x)
{
// on x64 it does
//
// 4863C2 movsxd rax, edx
// 8B0441 mov eax, dword ptr[rcx + 2 * rax]
//
// instead of loading just word
char implicit_nullcheck = c[x];
}
static void Main()
{
byte* page = VirtualAlloc(IntPtr.Zero, 4096, 0x1000 | 0x2000, 0x04);
Validate((char*)(page + 4096 - 4), 0); // OK
Console.WriteLine("1");
Validate((char*)(page + 4096 - 2), 0); // AVE
Console.WriteLine("2");
}
} |
I wonder if we can somehow change all |
Just curious, in what circumstances does the JIT do run-time null checks? I had assumed that it allows execution to hit an AV in the normal way, which the runtime then maps to NullReferenceException. |
… AccessViolationException details: dotnet/runtime#64657
* define NET7_0_PREVIEW2_OR_GREATER const for .NET 7 Preview2+ builds * don't use Regex.Count API for older versions of .NET 7 (used as baseline for monthly perf runs) * don't try to run AddRemoveFromDifferentThreads.ConcurrentStack benchmark on ARM64 as it hangs details: dotnet/runtime#64980 * don't try to run Json_FromString.Jil_ benchmark on ARM64 as it throws AccessViolationException details: dotnet/runtime#64657
When running the dotnet/performance benchmarks with 7.0 preview 1 bits on my mac M1 ARM64 device, I've found that the
MicroBenchmarks.Serializers.Json_FromString<MyEventsListerViewModel>.Jil_
test is consistently crashing withAccessViolationException
. I've debugged it and it seems to be a JIT bug. JIT generates an instruction with wrong scaling mode like this:The
x3
points to the first character of a string and w1 is an index into it. This instruction scales the index by 4 instead of just 2, getting out of the string and hitting an unmapped memory, which results in the reportedAccessViolationException
.I have captured the disassembly of the method with embedded IL here: https://gist.github.com/janvorli/643f0e3b3acacb083af3178b5a232bc2
The crash happens at 00000002842f832c. The
x3
is 0x113F64044, thew1
is 69626. The memory address accessed during the crash is 0x113fa802c. It is equal to 0x113F64044+4*69626.The whole string is this one:
I believe this is the source code at the failure point (the Read method seems to be inlined):
https://github.com/kevin-montrose/Jil/blob/9276eaa6a0aaea41d280ff01abeed56214f782df/Jil/Deserialize/Methods.ThunkReader.cs#L4453
Here is the stack trace of the exception:
Unfortunately, the runtime was a release build, so I couldn't get a JIT dump. However, the benchmark scripts allow to use a self-built runtime, so it should not be difficult to get it repro even with a checked build of the runtime.
Here are the repro steps:
The test run takes quite some time, but it always crashes at that place for me.
The text was updated successfully, but these errors were encountered: