runtime: AutoMapper crashes on .NET 6 iOS MAUI application mapping IEnumerable properties

Discussed in https://github.com/dotnet/maui/discussions/10500

<div type='discussions-op-text'>

Originally posted by busec0 October 5, 2022 AutoMapper doesn’t seem to work properly with a .NET 6 iOS MAUI Application. On Android, everything is working as expected. On iOS, it crashes trying to map two types that have an IEnumerable property:

e.g.

// - - - - - Models
public class MyClass
{
    public IEnumerable<int> Values { get; set; }
}

public class MyClassDto
{
    public IEnumerable<int> Values { get; set; }
}

// - - - - - AutoMapper Configuration 
var config = new MapperConfiguration(cfg => cfg.CreateMap<MyClass, MyClassDto>().ReverseMap());
_mapper = config.CreateMapper();

// - - - - - Mapping Code 
var myClass = new MyClass()
{
    Values = new List<int> { 1, 2, 3 }
};
// Works on Android, fails on iOS
var myClassDto = _mapper.Map<MyClassDto>(myClass);

Sample app to reproduce the issue: https://github.com/busec0/MauiAutomapper. Automapper code is on MainPage.xaml.cs

Does anyone know why the failure is happening on iOS only? Tested with Xamarin.iOS as well, and everything is working as expected there.

Stack Trace

Objective-C exception thrown.  Name: AutoMapper.AutoMapperMappingException Reason: Error mapping types.

Mapping types:
MyClass -> MyClassDto
MauiAutomapper.MyClass -> MauiAutomapper.MyClassDto

Type Map configuration:
MyClass -> MyClassDto
MauiAutomapper.MyClass -> MauiAutomapper.MyClassDto

Destination Member:
Values
 (AutoMapper.AutoMapperMappingException)
   at System.Linq.Expressions.Interpreter.ThrowInstruction.Run(InterpretedFrame frame)
   at System.Linq.Expressions.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Linq.Expressions.Interpreter.Interpreter.Run(InterpretedFrame frame)
   at System.Linq.Expressions.Interpreter.LightLambda.Run(Object[] arguments)
   at System.Linq.Expressions.Interpreter.CallInstruction.InterpretLambdaInvoke(LightLambda targetLambda, Object[] args)
   at System.Linq.Expressions.Interpreter.FuncCallInstruction`5[[System.Func`4[[MauiAutomapper.MyClass, MauiAutomapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[MauiAutomapper.MyClassDto, MauiAutomapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[AutoMapper.ResolutionContext, AutoMapper, Version=12.0.0.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005],[MauiAutomapper.MyClassDto, MauiAutomapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[MauiAutomapper.MyClass, MauiAutomapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[MauiAutomapper.MyClassDto, MauiAutomapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[AutoMapper.ResolutionContext, AutoMapper, Version=12.0.0.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005],[MauiAutomapper.MyClassDto, MauiAutomapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].Run(InterpretedFrame frame)
   at System.Linq.Expressions.Interpreter.Interpreter.Run(InterpretedFrame frame)
   at System.Linq.Expressions.Interpreter.LightLambda.Run(Object[] arguments)
   at MauiAutomapper.MainPage.OnCounterClicked(Object sender, EventArgs e) in /Users/sergiubulzan/Projects/tmp/MauiAutomapper/MauiAutomapper/MainPage.xaml.cs:line 23
   at Microsoft.Maui.Controls.Button.Microsoft.Maui.Controls.Internals.IButtonElement.PropagateUpClicked()
   at Microsoft.Maui.Controls.ButtonElement.ElementClicked(VisualElement visualElement, IButtonElement ButtonElementManager)
   at Microsoft.Maui.Controls.Button.SendClicked()
   at Microsoft.Maui.Controls.Button.Microsoft.Maui.IButton.Clicked()
   at Microsoft.Maui.Handlers.ButtonHandler.OnButtonTouchUpInside(Object sender, EventArgs e)
   at UIKit.UIControlEventProxy.Activated()
Collection was modified; enumeration operation may not execute. (System.InvalidOperationException)
   at System.Collections.Generic.List`1.Enumerator[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNextRare()
   at System.Collections.Generic.List`1.Enumerator[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
   at System.Linq.Expressions.Interpreter.FuncCallInstruction`2[[System.Collections.IEnumerator, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Boolean, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Run(InterpretedFrame frame)
   at System.Linq.Expressions.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Linq.Expressions.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

Native stack trace:
	0   CoreFoundation                      0x0000000110104d44 __exceptionPreprocess + 242
	1   libobjc.A.dylib                     0x000000011cfb7a65 objc_exception_throw + 48
	2   libxamarin-dotnet-debug.dylib       0x000000010bb80ddf xamarin_process_managed_exception + 943
	3   MauiAutomapper                      0x0000000102b5ad29 _ZL31native_to_managed_trampoline_10P11objc_objectP13objc_selectorPP11_MonoMethodj + 361
	4   MauiAutomapper                      0x0000000102ba0959 -[UIKit_UIControlEventProxy BridgeSelector] + 41
	5   UIKitCore                           0x0000000128684c87 -[UIApplication sendAction:to:from:forEvent:] + 83
	6   UIKitCore                           0x0000000127f13988 -[UIControl sendAction:to:forEvent:] + 110
	7   UIKitCore                           0x0000000127f13d8c -[UIControl _sendActionsForEvents:withEvent:] + 345
	8   UIKitCore                           0x0000000127f1026f -[UIButton _sendActionsForEvents:withEvent:] + 148
	9   UIKitCore                           0x0000000127f125e3 -[UIControl touchesEnded:withEvent:] + 485
	10  UIKitCore                           0x0000000128147905 _UIGestureEnvironmentUpdate + 8951
	11  UIKitCore                           0x0000000128145186 -[UIGestureEnvironment _updateForEvent:window:] + 897
	12  UIKitCore                           0x00000001286c8098 -[UIWindow sendEvent:] + 5290
	13  UIKitCore                           0x000000012869e160 -[UIApplication sendEvent:] + 820
	14  UIKitCore                           0x0000000128736cfd __dispatchPreprocessedEventFromEventQueue + 8713
	15  UIKitCore                           0x00000001287394a0 __processEventQueue + 8635
	16  UIKitCore                           0x000000012872fccd __eventFetcherSourceCallback + 232
	17  CoreFoundation                      0x0000000110071833 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
	18  CoreFoundation                      0x000000011007172b __CFRunLoopDoSource0 + 180
	19  CoreFoundation                      0x0000000110070bf8 __CFRunLoopDoSources0 + 242
	20  CoreFoundation                      0x000000011006b2f4 __CFRunLoopRun + 871
	21  CoreFoundation                      0x000000011006aa90 CFRunLoopRunSpecific + 562
	22  GraphicsServices                    0x000000011fd05c8e GSEventRunModal + 139
	23  UIKitCore                           0x000000012867e90e -[UIApplication _run] + 928
	24  UIKitCore                           0x0000000128683569 UIApplicationMain + 101
	25  libmonosgen-2.0.dylib               0x000000010c36ec42 do_icall + 194
	26  libmonosgen-2.0.dylib               0x000000010c36dc5d do_icall_wrapper + 253
	27  libmonosgen-2.0.dylib               0x000000010c35fe7a interp_exec_method + 2970
	28  libmonosgen-2.0.dylib               0x000000010c35e0ff interp_runtime_invoke + 239
	29  libmonosgen-2.0.dylib               0x000000010c255d3b mono_jit_runtime_invoke + 1227
	30  libmonosgen-2.0.dylib               0x000000010c178328 mono_runtime_invoke_checked + 136
	31  libmonosgen-2.0.dylib               0x000000010c17f0cb mono_runtime_exec_main_checked + 107
	32  libmonosgen-2.0.dylib               0x000000010c2b81e2 mono_jit_exec + 354
	33  libxamarin-dotnet-debug.dylib       0x000000010bb94e9d xamarin_main + 1949
	34  MauiAutomapper                      0x0000000102bec954 main + 52
	35  dyld                                0x000000010b768f21 start_sim + 10
	36  ???                                 0x000000020315651e 0x0 + 8641668382
	37  ???                                 0x0000000000000003 0x0 + 3
</div>

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 17 (11 by maintainers)

Most upvoted comments

To solve this, all the answers I see point to enabling the interpreter.

(Not gonna help with the problem but small explanation cannot hurt)

The UseInterpreter switch affects the Mono IL interpreter, ie. interpreting the IL byte code. While it relates to the same scenarios (not being able to use JIT) it’s different from the LINQ interpreter that you see in the stack traces. That’s an alternative implementation of the LINQ expression trees that avoids runtime code generation.