-
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
Crash on using Expression.Compile() in a release mode (iOS). #69410
Comments
@rolfbjarne / @stephen-hawley - should this move to https://github.com/xamarin/xamarin-macios ? |
@Eilon this should go to dotnet/runtime, it's an issue with either the AOT compiler or the BCL. |
Tagging subscribers to this area: @cston Issue DetailsDescriptionPlease see following project to reproduce this issue: https://github.com/JaneySprings/MauiReflectionBug Steps to Reproduce
Version with bugRelease Candidate 3 (current) Last version that worked wellUnknown/Other Affected platformsiOS Affected platform versionsiOS 15.4 Did you find any workaround?no Relevant log outputSystem.ExecutionEngineException: Attempting to JIT compile method (wrapper delegate-invoke) int :invoke_callvirt_int_MyItem (reflecBug.MyItem) while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.
|
Tagging subscribers to 'os-ios': @steveisok, @akoeplinger Issue DetailsDescriptionPlease see following project to reproduce this issue: https://github.com/JaneySprings/MauiReflectionBug Steps to Reproduce
Version with bugRelease Candidate 3 (current) Last version that worked wellUnknown/Other Affected platformsiOS Affected platform versionsiOS 15.4 Did you find any workaround?no Relevant log outputSystem.ExecutionEngineException: Attempting to JIT compile method (wrapper delegate-invoke) int :invoke_callvirt_int_MyItem (reflecBug.MyItem) while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.
|
I can reproduce in .net 6. Under .NET 7, the message is a bit more friendly
@akoeplinger do you know of any mono trickery that was done in the past? @MichalStrehovsky do you have any insight into if this can even work in runtime? |
Following adapted snippet placed in a console app works with NativeAOT full AOT mode, so this looks like it has more to do with how S.L.Expressions is configured for iDevices than with AOT: using System.Linq.Expressions;
var item = new MyItem();
item.Id = 100;
try
{
Console.WriteLine(GetValue(item));
}
catch (Exception e)
{
Console.WriteLine(e);
}
static object GetValue(object component)
{
Func<object, object> propertyAccessorDelegate = CompileLambda();
return propertyAccessorDelegate(component);
}
static Func<object, object> CompileLambda()
{
ParameterExpression parameter = Expression.Parameter(typeof(object), "p");
MemberExpression property = Expression.Property(Expression.Convert(parameter, typeof(MyItem)), "Id");
Expression<Func<object, object>> lambda = Expression.Lambda<Func<object, object>>(Expression.Convert(property, typeof(object)), parameter);
return lambda.Compile();
}
public class BaseItem
{
int id;
public virtual int Id
{
get => id;
set => this.id = value;
}
}
public class MyItem : BaseItem
{
int id;
//Some attributes....
public override int Id { get => base.Id; set => base.Id = value; }
} The The originally reported issue ("Attempting to JIT compile method") might be related to what I called out in #61952 in my comments around iDevices/iOS: there are more codepaths in S.L.Expressions that should be activated for a full AOT experience. Some of these codepaths require extra runtime support - it's code around CanEmitObjectArrayDelegate and CanCreateArbitraryDelegates. I think the tests that got disabled for iDevices in #54970 are testing this functionality but it doesn't look like the failures got looked at since then. |
Hello, we are developing DevExpress .NET MAUI controls and experienced the same issue a lot in our DevExpress.Data library that provides many helpful classes to our customers and for internal use. We use Expression.Compile() very widely in our codebase and we didn't experience any issues with it in Xamarin.Forms, but experienced random crashes a lot in MAUI. There is another one same issue, that we've reported recently - #71323. That issues have a very high priority for us because we can't release our components with random crashes. Could you provide any generic workaround for these issues? Thank you for your help. |
So for this error:
What happens is that linq creates a |
Can't repro the "Expression must be readable" error from #69410 (comment) with dotnet/runtime main on MacCatalyst. Same error as ios device: I think the question is how did this work with mono/mono linq for Xamarin.Forms - it doesn't seem like this should be possible. I think one workaround on maui might be to enable the mono interpreter as a backup to AOT. |
Running with full-aot+interp fixes the ExecutionEngineException for me. |
@rolfbjarne Is this mode supported in xam iOS? |
As I wrote above: "The originally reported issue ("Attempting to JIT compile method") might be related to what I called out in #61952 in my comments around iDevices/iOS: there are more codepaths in S.L.Expressions that should be activated for a full AOT experience. Some of these codepaths require extra runtime support - it's code around CanEmitObjectArrayDelegate and CanCreateArbitraryDelegates." Specifically to avoid landing in
For NativeAOT, we set |
@MichalStrehovsky It appears that |
This is because of this: runtime/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj Lines 12 to 17 in 12a6db4
We want to run IPConstProp for iDevices because we need it to get rid of the Expressions IL Compiler, but we don't want to constant propagate the definition of CanCreateArbitraryDelegates. Possible solutions:
|
Adding this to the csproj: <PropertyGroup>
<UseInterpreter>true</UseInterpreter>
</PropertyGroup> will enable the interpreter, but still AOT every assembly (although I'm not sure if that's equivalent to "full aot"). |
Thank you for the workaround. It works, but it's still very weird bug for us because this property can be set in application, not in libraries, which we distribute. And our customers will still run into this issue. |
I also confirm that this workaround works. Thank goodness! |
How did this even work in Xamarin.iOS Apps before and started breaking targeting net6.0-ios? This is a huge regression! |
Yeah I just ran into this for a second time in a Maui app targeting net6. Its especially pernicious because in both cases the app is running just fine for months before starting to crash at runtime suddenly, after a seemingly innocent change. The access patterns before and after the crashes are largely the same, it just so happens that for whatever reason the compiler optimizes/decides slightly differently in one case vs the other. Very frustrating. |
I should also note that in the first case I ran into this, the |
Is there any update on this regression? It is rather a problem when migrating a Xamarin.iOS project to .Net7-iOS. |
also impacting my application, interpreter is definetely not an option as the performance is unacceptable |
Can you try this:
This will enable the interpreter, but still AOT compile all the assemblies. This may still fix this particular issue (because the app now has interpreter support at runtime), while keeping performance acceptable. |
Couldn't private static bool CanCreateArbitraryDelegates => RuntimeFeature.IsDynamicCodeSupported; |
That might work: it was recently done to one of the other S.L.Expressions feature switches as well: #80759. |
If this:
is the only change required, I can give it a try locally and see how it affects the app size. |
The reason why the repro sample shows a different error message, than what was originally reported, is because ILLinker trims out a property in such way that it breaks the execution before it reaches the actual problem (covering it up). This is observable during compilation with warning messages like:
Rooting the assembly containing the repro source code, with something like: <ItemGroup>
<TrimmerRootAssembly Include="<assembly-containing-the-repro>" />
</ItemGroup> reveals the reported PS I assume this was not visible with dotnet6 as the ILLinker got improved in the meantime. |
The ExecutionEngineException is supposed to be fixed in net8 by: |
Unfortunately, that fix does not seem to resolve the issue reported here. I have managed to reproduce the reported issue with fc75f7e on the main branch by adapting the HelloiOS accordingly and running it on a device. Repro steps
The console log shows:
Full log can be found here: https://gist.github.com/ivanpovazan/0f8bda708344858a6dd8c9efbddeea6c |
I have verified locally that this has been fixed via: #88539 The mentioned fix will become available in @JaneySprings could you please confirm if this solved your problem? |
@ivanpovazan Still reproducing on my example from this issue (net8.0-ios | release | device) 😢 .NET version: Preview 7 is not available globally yet? |
Thank you for checking it out, but unfortunately the fix is available only in preview 7.
Correct. Preview 7 is not available officially yet. It will be released early to mid August. I have verified that the sample works with the latest nightly build: |
I am closing the issue as I have verified that the issue has been fixed with the official .NET8 preview 7 release. |
Description
Please see following project to reproduce this issue: https://github.com/JaneySprings/MauiReflectionBug
Same code works perfectly in Xamarin.Forms (iOS release).
Steps to Reproduce
Version with bug
Release Candidate 3 (current)
Last version that worked well
Unknown/Other
Affected platforms
iOS
Affected platform versions
iOS 15.4
Did you find any workaround?
no
Relevant log output
The text was updated successfully, but these errors were encountered: