runtime: [BUG] ExecutionEngineException when deserializing generic [DataContract] on iOS (Realease Build, only through app store)
Description
Exception thrown when deserializing datacontract on iOS. The problem only occurs when the app has been deployed through AppStore/TestFlight.
System.ExecutionEngineException: Attempting to JIT compile method '(wrapper delegate-invoke) void <Module>:invoke_callvirt_void_Element_string (AnleggsSentralen.Checklist.Element,string)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.
at System.Runtime.Serialization.FastInvokerBuilder.<>c__DisplayClass12_1`2[[AnleggsSentralen.Checklist.Element, AnleggsSentralen.Checklist, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<CreateSetterInternal>b__1(Object& , Object )
at System.Runtime.Serialization.ReflectionReader.ReflectionSetMemberValue(Object& , Object , DataMember )
at System.Runtime.Serialization.ReflectionReader.ReflectionReadMember(XmlReaderDelegator , XmlObjectSerializerReadContext , ClassDataContract , Object& , Int32 , DataMember[] )
at System.Runtime.Serialization.ReflectionXmlReader.ReflectionReadMembers(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] , ClassDataContract , Object& )
at System.Runtime.Serialization.ReflectionReader.ReflectionReadClass(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] , ClassDataContract )
at System.Runtime.Serialization.ReflectionXmlClassReader.ReflectionReadClass(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] )
at System.Runtime.Serialization.DataContracts.ClassDataContract.ReadXmlValue(XmlReaderDelegator , XmlObjectSerializerReadContext )
at System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract , XmlReaderDelegator )
at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract& dataContract)
at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)
at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator , Boolean , DataContractResolver )
at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator , Boolean , DataContractResolver )
at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader )
at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(Stream )
at AnleggsSentralen.Checklist.Checklist.Load(Stream stream)
at AnleggsSentralen.Checklist.Checklist.LoadAsync(Stream stream)
at AnleggsSentralen.Client.Services.ChecklistService.GetChecklistTemplateAsync(Int32 id)
at AnleggsSentralen.App.Services.DataLake.<GetDraftAsync>d__27`1[[AnleggsSentralen.Checklist.Checklist, AnleggsSentralen.Checklist, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
at AnleggsSentralen.App.ViewModels.ChecklistViewModel.LoadChecklistFromTemplateAsync()
at Herreruud.Framework.Mvvm.AsyncHelper.TraceExceptions(Func`1 factory, String method, String path)
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
- net7.0-ios
- ios
- AppStore
- Arm64
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:
// 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)
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 39 (22 by maintainers)
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,
RuntimeFeature.IsDynamicCodeSupported
becomes true.@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:
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
if
should probably fix it as well.Also, why does this not occur for debug builds? I have a debug build in production in the AppStore right now (unfortunatly).
@LeVladIonescu I see that the above dump didn’t include SDK version:
7.0.100