-
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
[BUG] ExecutionEngineException when deserializing generic [DataContract] on iOS (Realease Build, only through app store) #78889
Comments
Tagging subscribers to 'os-ios': @steveisok, @akoeplinger Issue DetailsDescriptionException thrown when deserializing datacontract on iOS.
Reproduction StepsDeserialize generic datacontract on iOS in release build through AppStore/TestFlight. Expected behaviorThe datacontract should deserialize Actual behaviorExecutionEngine is thrown Regression?No response Known WorkaroundsNo response Configuration
Other informationIn the file "src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/AccessorBuilder.cs", I can find the following code, that I suspect is the problem: // If either of the arguments to MakeGenericMethod is a valuetype, this is going to cause JITting.
// Only JIT if dynamic code is supported.
if (RuntimeFeature.IsDynamicCodeSupported || (!declaringType.IsValueType && !propertyType.IsValueType))
{
#pragma warning disable IL3050 // AOT compiling should recognize that this call is gated by RuntimeFeature.IsDynamicCodeSupported.
var createSetterGeneric = s_createSetterInternal.MakeGenericMethod(propInfo.DeclaringType!, propInfo.PropertyType).CreateDelegate<Func<PropertyInfo, Setter>>();
#pragma warning restore IL3050 // Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
return createSetterGeneric(propInfo);
}
else
{
return (ref object obj, object? val) =>
{
propInfo.SetValue(obj, val);
};
} Also, The method itself is annotated with: [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2060:MakeGenericMethod",
Justification = "The call to MakeGenericMethod is safe due to the fact that FastInvokerBuilder.CreateSetterInternal<T, T1> is not annotated.")]
public static Setter CreateSetter(MemberInfo memberInfo)
|
/cc @SamMonoRT |
@AbstractionsAs, if you add |
I tried that - but it still doesn't, for some reason...
Skaff deg Outlook for Android<https://aka.ms/ghei36>
…________________________________
From: Steve Pfister ***@***.***>
Sent: Monday, November 28, 2022 6:33:43 PM
To: dotnet/runtime ***@***.***>
Cc: Christian Ruud ***@***.***>; Mention ***@***.***>
Subject: Re: [dotnet/runtime] [BUG] ExecutionEngineException when deserializing generic [DataContract] on iOS (Realease Build, only through app store) (Issue #78889)
@AbstractionsAs<https://github.com/AbstractionsAs>, if you add <UseInterpreter>true</UseInterpreter> to your project, this should work. As your description shows, the problem is that creating delegates on the fly is something that is not currently supported in Mono AOT.
—
Reply to this email directly, view it on GitHub<#78889 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AXR4SXLSTV4TWMW6M4D64DLWKTUHPANCNFSM6AAAAAASMUCSXY>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
@steveisok THis is what I've tried in the .csproj. Any idea why this doesn't have any effect? This is a blocker for me.. <PropertyGroup Condition="$(TargetFramework.Contains('-ios')) and '$(Configuration)' == 'Release'">
<RuntimeIdentifier>ios-arm64</RuntimeIdentifier>
<ArchiveOnBuild>true</ArchiveOnBuild>
<UseInterpereter>true</UseInterpereter>
<AdditionalArgs>--interpreter</AdditionalArgs>
</PropertyGroup> |
I don't think you need @AbstractionsAs, you still get the same exception even with interpreter enabled? |
@steveisok Yeah - same exception. It doesn't seem like It seems to me that the code in |
@AbstractionsAs Can you please provide a sample app which can reproduce the issue? |
@LeVladIonescu Can I send you a zip with some of my code files? The app itself is quite large, and it uses a ton of packages from our private feeds - including the one containing the datacontracts. Perhaps if I send you the datacontracts, and the code we use to deserialize? It only fails when pushed through the App Store (the page does not render, and the exception is sent to my logging server), but everything works like a charm when debugging locally. |
@LeVladIonescu If not I'll attempt to create another, simpler, app with the problem, but I'll have to actually push it all the way though the app store to reproduce the problem |
@AbstractionsAs Creating a simpler app would be easier for me to understand the problem. Let me know if you will do that, otherwise we will stick to those bigger source codes. |
AOT Serialization Bug.zip |
@AbstractionsAs Thanks for it |
@LeVladIonescu Is there any update or timeline on this? It's a big blocker for me... |
@AbstractionsAs I had a lot of issues regarding my certificates, I've resolved them now. I still get an error for the release build right now, debug build works properly. Working on it right now.. |
@AbstractionsAs what IOS Distribution Channel have you used when publishing the archive you provided? |
@LeVladIonescu Thanks. Distribution channel is "App Store", I think. |
@AbstractionsAs just to confirm it, you've managed to reproduce the bug with this archive by deploying it on TestFlight, right?
|
@LeVladIonescu Yeah, with this build I've reproduced it both locally and on TestFlight. I believe it's the latest versions of everything, but I'll double check that shortly |
@LeVladIonescu Here's everything, I think:
|
@LeVladIonescu I see that the above dump didn't include SDK version: |
Hi @AbstractionsAs , I wasn't able to reproduce this so I suggest to have a conversation on Discord whenever you are available. (join Dotnet Evolution Channel on Discord - https://aka.ms/dotnet-discord) My versions : Visual Studio Enterprise 2022 for Mac SDK Version: 7.0.101 Xamarin.Profiler Apple Developer Tools Xamarin.iOS |
@LeVladIonescu I've never used discord before, but I'll install it and connect after my next meeting. That ok? |
@AbstractionsAs that's alright. Here is my username : LeVladIonescu13#0017 |
@LeVladIonescu Any progress on this? |
@AbstractionsAs working on it.. |
@AbstractionsAs Can you please double check if |
@LeVladIonescu Sorry, I've been away. The setting has no effect (that I can tell) on my main project. I haven't tried it with the demo project. I still think the following snippet reveals th eproblem, though: if (RuntimeFeature.IsDynamicCodeSupported || (!declaringType.IsValueType && !propertyType.IsValueType)) The correct way of fixning it might be figuring out why the strings in question causes JIT - given that strings are not value types, but simply removing the second part of the Also, why does this not occur for debug builds? I have a debug build in production in the AppStore right now (unfortunatly). |
That would be a performance regression. In the BCL we assume generic code over reference type can be shared and the AOT compiler generates it when the target is an obvious target of reflection like this. Generic code over value types cannot be shared without performance regressions, which is why we fall back to just using reflection since it's going to be slower with AOT either way. |
I believe interpreter should be on by default in debug builds, which is why it's working for you. I suspect that property is somehow not set in your release project. In interpreter mode, |
@steveisok Even if Since this causes JIT, we can conclude that the premise that reference types will not cause JIT'ing is false... |
@MichalStrehovsky Yeah, it will. But not working at all seems a greater regression.. I currently have debug builds in prduction, which is a much greater regression. Since none of the types are values types (class, string), then the premise that reference types will not cause JIT'ing cannot hold.. Is it possible that there are some custom adaptations made elsewhere for strings (handling them a certain way) that means they behave differently from other reference types in this case? |
Whats happening here is that the BCL is creating bound delegates, i.e. delegates with a null target, which when called, will make a virtual call to their bound method using their first argument as the receiver. Mono implements this using these 'invoke_callvirt_void_Element_string' wrapper methods generated at runtime. But since the wrapper methods depend on both the delegate type and the bound method to make the virtual call, they cannot be generated at AOT time since the AOT compiler can't determine that a particular combination of delegate type and bound method will be needed at runtime. |
@vargaz But if the |
Testcase:
|
For NativeAOT, we generate these ahead of time for each delegate type in the app. It costs some size, but the size is a fixed per-delegate overhead and this is guaranteed not to fail at runtime. For open instance delegates the generated thunk looks like this: https://github.com/dotnet/runtime/blob/main/src/coreclr/tools/Common/TypeSystem/IL/Stubs/DelegateThunks.cs#L150-L227 There is extra code to initialize a new instance of such delegate properly. Delegates on CoreCLR-JIT and CoreCLR-AOT have 4 instance fields - their meaning is overloaded depending on what kind of delegate that is. |
Looks like mono needs to do the same, i.e. resolve the called method pointer using an icall instead of hardcoding the called method into the wrapper. |
@AbstractionsAs can you follow these steps https://learn.microsoft.com/en-us/visualstudio/ide/msbuild-logs?view=vs-2022 to create a detailed log for verifying that UseInterpreter is properly set to true for your Release build? |
This should be fixed by #85643. |
Description
Exception thrown when deserializing datacontract on iOS.
The problem only occurs when the app has been deployed through AppStore/TestFlight.
Reproduction Steps
Deserialize generic datacontract on iOS in release build through AppStore/TestFlight.
I am unable to reproduce locally.
Expected behavior
The datacontract should deserialize
Actual behavior
ExecutionEngine is thrown
Regression?
No response
Known Workarounds
No response
Configuration
Other information
In the file "src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/AccessorBuilder.cs", I can find the following code, that I suspect is the problem:
Also, The method itself is annotated with:
The text was updated successfully, but these errors were encountered: