roubachof/Sharpnado.CollectionView

Immediate crash in Release-build for Maui

Closed this issue · 8 comments

Platform (please complete the following information):

  • OS: [Both]
  • Device: [Samsung 10 SE, Iphone 14/(happens on all devices)]
  • Sdk vervion: [iOS > 14.2/Android SDK > 26.0]
  • Maui: [6.0.406]

Describe the bug

Opening a page with a sharpnado collectionview causes the app to crash in release build.

It works fine in develpoment, but when optimizing the app for a release-build it immediately crashes when the page is opened. It doesn't crash until the page where sharpnado is referenced is opened.

From our logs it appears to throw System.MethodAccessException

By googling the exception some people suggest to add the following "interpreter" compiler flag

<UseInterpreter>true</UseInterpreter>

We already have this on IOS though and also experience it there.

It can all be reproduced by building the MauiSample in release mode. Here it crashes on startup, because sharpnado is referenced on the initial page.

Sharpnado solved some of our other problems in .NET Maui, so we really hope there is a solution 🙏

Thank you for an awesome library!

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://github.com/roubachof/Sharpnado.CollectionView/tree/main/Maui/MauiSample
  2. Open the terminal
  3. dotnet build MauiSample.csproj -c Release -f net6.0-android
  4. Open bin -> bin\Release\net6.0-android
  5. Transfer com.sharpnado.collectionview-Signed.apk to your physical phone
  6. Attempt to open it and notice it immediately crashes

Exceptions (if applicable)
Copy paste the exception and the stack trace

Unhandled Exception:
System.MethodAccessException

Screenshots (if applicable)
image

Hi!
I reproduced it with logcat. Please when you do have a crash in release use logcat (from android studio) to get logs from your device:

image

This is in fact a .net maui issue: dotnet/maui#7331
The workaround is here: dotnet/maui#8184

Or you can just upgrade to .net7

oops, wrong button :)

Thanks for your reply.

Yea upgrading to .net7 is definitely on our roadmap.

We don't use any ZIndexes in our project, though that does appear to fix the sample app!

I wonder if you can deduce anything from our stacktrace:

App.Pages.Tabs.MyMembersPage.<InitializeComponent>typedBindingsM__710(MyMembersPageViewModel , ObservableRangeCollection`1 )
Microsoft.Maui.Controls.Internals.TypedBinding`2[[ViewModels.Pages.Tabs.MyMembersPageViewModel, ViewModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Sharpnado.CollectionView.ViewModels.ObservableRangeCollection`1[[Models.MyMemberItems.MyMemberItem, Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Sharpnado.CollectionView.Maui, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null]].ApplyCore(Object sourceObject, BindableObject target, BindableProperty property, Boolean fromTarget)
Microsoft.Maui.Controls.Internals.TypedBinding`2[[ViewModels.Pages.Tabs.MyMembersPageViewModel, ViewModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Sharpnado.CollectionView.ViewModels.ObservableRangeCollection`1[[Models.MyMemberItems.MyMemberItem, Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Sharpnado.CollectionView.Maui, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null]].Apply(Boolean fromTarget)
Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, Boolean silent)
Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)
Microsoft.Maui.Controls.Internals.TypedBinding`2[[ViewModels.Pages.Tabs.MyMembersPageViewModel, ViewModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Sharpnado.CollectionView.ViewModels.ObservableRangeCollection`1[[Models.MyMemberItems.MyMemberItem, Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Sharpnado.CollectionView.Maui, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null]].ApplyCore(Object sourceObject, BindableObject target, BindableProperty property, Boolean fromTarget)
Microsoft.Maui.Controls.Internals.TypedBinding`2[[ViewModels.Pages.Tabs.MyMembersPageViewModel, ViewModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Sharpnado.CollectionView.ViewModels.ObservableRangeCollection`1[[Models.MyMemberItems.MyMemberItem, Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Sharpnado.CollectionView.Maui, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null]].Apply(Object context, BindableObject bindObj, BindableProperty targetProperty, Boolean fromBindingContextChanged)
Microsoft.Maui.Controls.BindableObject.ApplyBindings(Boolean skipBindingContext, Boolean fromBindingContextChanged)
Microsoft.Maui.Controls.BindableObject.SetInheritedBindingContext(BindableObject bindable, Object value)
Microsoft.Maui.Controls.Element.SetChildInheritedBindingContext(Element child, Object context)
Microsoft.Maui.Controls.Element.<OnBindingContextChanged>b__82_0(BindableObject child, Object bc)
Microsoft.Maui.Controls.BindableObjectExtensions.PropagateBindingContext[Element](BindableObject self, IEnumerable`1 children, Action`2 setChildBindingContext)
Microsoft.Maui.Controls.Element.OnBindingContextChanged()
Microsoft.Maui.Controls.VisualElement.OnBindingContextChanged()
Microsoft.Maui.Controls.View.OnBindingContextChanged()
Microsoft.Maui.Controls.Grid.OnBindingContextChanged()
Microsoft.Maui.Controls.BindableObject.SetInheritedBindingContext(BindableObject bindable, Object value)
Microsoft.Maui.Controls.Element.SetChildInheritedBindingContext(Element child, Object context)
Microsoft.Maui.Controls.Element.<OnBindingContextChanged>b__82_0(BindableObject child, Object bc)
Microsoft.Maui.Controls.BindableObjectExtensions.PropagateBindingContext[Element](BindableObject self, IEnumerable`1 children, Action`2 setChildBindingContext)
Microsoft.Maui.Controls.Element.OnBindingContextChanged()
Microsoft.Maui.Controls.VisualElement.OnBindingContextChanged()
Microsoft.Maui.Controls.View.OnBindingContextChanged()
Microsoft.Maui.Controls.Grid.OnBindingContextChanged()
Microsoft.Maui.Controls.BindableObject.SetInheritedBindingContext(BindableObject bindable, Object value)
Microsoft.Maui.Controls.Element.SetChildInheritedBindingContext(Element child, Object context)
Microsoft.Maui.Controls.Element.<OnBindingContextChanged>b__82_0(BindableObject child, Object bc)
Microsoft.Maui.Controls.BindableObjectExtensions.PropagateBindingContext[Element](BindableObject self, IEnumerable`1 children, Action`2 setChildBindingContext)
Microsoft.Maui.Controls.Element.OnBindingContextChanged()
Microsoft.Maui.Controls.VisualElement.OnBindingContextChanged()
Microsoft.Maui.Controls.View.OnBindingContextChanged()
Microsoft.Maui.Controls.Grid.OnBindingContextChanged()
Microsoft.Maui.Controls.BindableObject.SetInheritedBindingContext(BindableObject bindable, Object value)
Microsoft.Maui.Controls.Element.SetChildInheritedBindingContext(Element child, Object context)
Microsoft.Maui.Controls.TemplatedPage.SetChildInheritedBindingContext(Element child, Object context)
Microsoft.Maui.Controls.Element.<OnBindingContextChanged>b__82_0(BindableObject child, Object bc)
Microsoft.Maui.Controls.BindableObjectExtensions.PropagateBindingContext[Element](BindableObject self, IEnumerable`1 children, Action`2 setChildBindingContext)
Microsoft.Maui.Controls.Element.OnBindingContextChanged()
Microsoft.Maui.Controls.VisualElement.OnBindingContextChanged()
Microsoft.Maui.Controls.Page.OnBindingContextChanged()
Microsoft.Maui.Controls.ContentPage.OnBindingContextChanged()
Microsoft.Maui.Controls.BindableObject.BindingContextPropertyChanged(BindableObject bindable, Object oldvalue, Object newvalue)
Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, Boolean silent)
Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)
Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value, Boolean fromStyle, Boolean checkAccess)
Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value)
Microsoft.Maui.Controls.BindableObject.set_BindingContext(Object value)
App.Pages.Tabs.MyMembersPage..ctor(MyMembersPageViewModel vm)
System.Reflection.RuntimeConstructorInfo.InternalInvoke(Object , Object[] , Boolean )
System.Reflection.RuntimeConstructorInfo.DoInvoke(Object , BindingFlags , Binder , Object[] , CultureInfo )
System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags , Binder , Object[] , CultureInfo )
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite , RuntimeResolverContext )
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite , RuntimeResolverContext )
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite , RuntimeResolverContext )
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite , RuntimeResolverContext )
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type )
System.Collections.Concurrent.ConcurrentDictionary`2[[System.Type, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Func`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope, Microsoft.Extensions.DependencyInjection, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].GetOrAdd(Type , Func`2 )
Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type , ServiceProviderEngineScope )
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type )
Microsoft.Maui.MauiContext.WrappedServiceProvider.GetService(Type serviceType)
Microsoft.Maui.Controls.ShellContent.<>c__DisplayClass19_0.<Microsoft.Maui.Controls.IShellContentController.GetOrCreateContent>b__0()
Microsoft.Maui.Controls.ElementTemplate.CreateContent()
Microsoft.Maui.Controls.Internals.DataTemplateExtensions.CreateContent(DataTemplate self, Object item, BindableObject container)
Microsoft.Maui.Controls.ShellContent.Microsoft.Maui.Controls.IShellContentController.GetOrCreateContent()
Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRenderer.OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
AndroidX.Fragment.App.Fragment.n_OnCreateView_Landroid_view_LayoutInflater_Landroid_view_ViewGroup_Landroid_os_Bundle_(IntPtr , IntPtr , IntPtr , IntPtr , IntPtr )
Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLLL_L(_JniMarshal_PPLLL_L , IntPtr , IntPtr , IntPtr , IntPtr , IntPtr )

There seems to be an accessibility issue with the DisplayedMember property setter of your view model.
Maybe your setter is private or something. But anyways, this has nothing to do with the CollectionView I'm afraid....

The thing is our app only crashes when we introduce Sharpnado. If we use a regular collectionview we experience no such exception, so there's something going on.

I'll work on trying to create a reproducible sample - the sample app does indeed work now :-)

There is something funky going on between your DisplayedMember and the ItemsSource

let me see MyMembersPageViewModel

I finally figured it out - should have probably figured it out sooner 😳

Our collection had a private setter i.e:

public ObservableCollection<MyMemberItem> DisplayedMembers { get; private set; } = new();

I'm still a little confused about how it works in debug mode but not in release mode

I told you that 5 days ago...