Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Bug] [iOS] Freezing/App Crash during Navigation - new in iOS 15 #14783

Open
justin-loverme opened this issue Oct 22, 2021 · 41 comments
Open

[Bug] [iOS] Freezing/App Crash during Navigation - new in iOS 15 #14783

justin-loverme opened this issue Oct 22, 2021 · 41 comments
Labels
i/high Completely doesn't work, crashes, or is unusably slow, has no obvious workaround; occurs less often iOS 15 p/iOS 🍎 s/needs-info ❓ A question has been asked that requires an answer before work can continue on this issue. s/unverified New report that has yet to be verified t/bug 🐛
Projects

Comments

@justin-loverme
Copy link

After the release of iOS 15 we have been seeing an issue of freezing and then an app crash for our application and it seems to be a native library that we cannot debug.
All of our Nugets are up-to-date including running on the latest Xamarin.Forms of 5.0.0.2196. We have tried build the app through App Center with its latest tools (builds will fail if you attempt to use anything previous to Xamarin.iOS 15 and Xcode 13). We have tried building using a host Mac running Xamarin.iOS 15.0.0.6 as well as using a PC and remote connecting to a host Mac to force it to build with Xamarin.iOS 15.0.0.8. We have tried installing the Visual Studio 2022 Preview and using the new Xamarin iOS tools there as well.
This issue does not occur on iOS 14.8 devices, only iOS 15.0.x

  1. A summary of the issue is this (this does not happen every attempt of this cycle, sometimes it can take a couple tries, other times it can take more, but rarely is it the first try)
  2. User logs into our App and our landing page is a SyncFusion Calendar control with many events and data load behind it
  3. User then taps into an event which loads a Xamarin TabbedPage and has about 10 inner pages for tabs - again a data heavy load
  4. The user can move around the different tabs fine, scroll up and down data fine, ect within the TabbedPage stacktrace
  5. The user then uses the back button to go back to the SyncFusion Calendar and can at first tap to different dates but then there is a freeze after 1 or 2 seconds and eventual crash with the Report below.

We think this issue has to do with some kind of garbage collection or disposing of the large memory use that the TabbedPage had since the freeze doesn’t happen instantly on ‘Back’ navigation to the SFCalendar
Again, that cycle doesn't always happen, the user can repeat steps 3-5 and eventually one of the cycles will result in the below:

=================================================================
Native Crash Reporting

Got a segv while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.

=================================================================
Native stacktrace:

0x108a59460 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : mono_dump_native_crash_info
0x108a4f5d8 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : mono_handle_native_crash
0x108a5d8e0 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : mono_sigsegv_signal_handler_debug
0x1f22a1c18 - /usr/lib/system/libsystem_platform.dylib : <redacted>
0xffffff819ac6da84 - Unknown
0x19ac6da84 - /usr/lib/libobjc.A.dylib : <redacted>
0x184d42e34 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore : <redacted>
0x108c17fb0 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : xamarin_invoke_objc_method_implementation
0x108c18134 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : xamarin_release_trampoline
0x10265ac74 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : -[Xamarin_Forms_Platform_iOS_PageRenderer release]
0x182704b2c - /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation : <redacted>
0x185471cac - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore : <redacted>
0x19ac73f18 - /usr/lib/libobjc.A.dylib : <redacted>
0x19ac70c14 - /usr/lib/libobjc.A.dylib : objc_destructInstance
0x19ac7a338 - /usr/lib/libobjc.A.dylib : _objc_rootDealloc
0x184e79e80 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore : <redacted>
0x184d42f9c - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore : <redacted>
0x19ac73f18 - /usr/lib/libobjc.A.dylib : <redacted>
0x19ac70c14 - /usr/lib/libobjc.A.dylib : objc_destructInstance
0x19ac7a338 - /usr/lib/libobjc.A.dylib : _objc_rootDealloc
0x184e79e80 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore : <redacted>
0x184d42f9c - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore : <redacted>
0x184f131a0 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore : <redacted>
0x108c1564c - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : xamarin_release_managed_ref
0x103a35cac - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : wrapper_managed_to_native_Foundation_NSObject_xamarin_release_managed_ref_intptr_bool
0x1039d9b30 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : Foundation_NSObject_ReleaseManagedRef
0x1039dce74 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : Foundation_NSObject_NSObject_Disposer_Drain_Foundation_NSObject
0x102a81d70 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr
0x108a60d28 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : mono_jit_runtime_invoke
0x108b1a8b4 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : mono_runtime_invoke_checked
0x108b1e0f4 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : mono_runtime_invoke
0x1026474e0 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : _ZL31native_to_managed_trampoline_46P11objc_objectP13objc_selectorPP11_MonoMethodS0_j
0x102647368 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : +[__NSObject_Disposer drain:]
0x183f35e0c - /System/Library/Frameworks/Foundation.framework/Foundation : <redacted>
0x182789030 - /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation : <redacted>
0x182799cf0 - /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation : <redacted>
0x1826d3ff8 - /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation : <redacted>
0x1826d9804 - /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation : <redacted>
0x1826ed3c8 - /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation : CFRunLoopRunSpecific
0x185093060 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore : <redacted>
0x19defe38c - /System/Library/PrivateFrameworks/GraphicsServices.framework/GraphicsServices : GSEventRunModal
0x184e10b8c - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore : UIApplicationMain
0x103a34688 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : wrapper_managed_to_native_UIKit_UIApplication_UIApplicationMain_int_string___intptr_intptr
0x102a81d70 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr
0x1026907e4 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : Avianis_App_Platorm_Application_Main_string__
0x108a60d28 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : mono_jit_runtime_invoke
0x108b1a8b4 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : mono_runtime_invoke_checked
0x10397b5c0 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : UIKit_UIApplication_Main_string___System_Type_System_Type
0x108b20b68 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : mono_runtime_exec_main_checked
0x108a3f138 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : mono_jit_exec
0x108c24bf4 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : xamarin_main
0x10268f184 - /private/var/containers/Bundle/Application/B3BD93F9-3D6A-4799-BC38-D4E81FB1A2E0/Avianis.app/Avianis : main
0x10f49da24 - Unknown

=================================================================
Basic Fault Address Reporting:

Memory around native instruction pointer (0x19ac72378):0x19ac72368 3f 3d 00 f1 a3
00 00 54 c9 12 40 f9 29 ad 7d 92 ?=
.....T..@.).}.
0x19ac72378 37 01 40 b9 b7 00 00 37 08
81 7d 92 08 11 40 f9 7.@....7..}...@.
0x19ac72388 08 ad
7d 92 17 01 40 b9 08 00 80 52 7a d0 3b d5 ..}...@....Rz.;.
0x19ac72398 49 1b 40 b9 f9 8a 20 90 39 f3 24 91 29 7f e8 88 I.@... .
9.$.)...

Managed Stacktrace:
  at <unknown> <0xffffffff>
  at Foundation.NSObject:xamarin_release_managed_ref <0x00007>
  at Foundation.NSObject:ReleaseManagedRef <0x0004f>
  at NSObject_Disposer:Drain <0x00173>
  at System.Object:runtime_invoke_dynamic <0x0010f>
  at <unknown> <0xffffffff>
  at UIKit.UIApplication:UIApplicationMain <0x00007>
  at UIKit.UIApplication:Main <0x000ef>
  at Avianis.Platorm.Application:Main <0x000a3>
  at System.Object:runtime_invoke_dynamic <0x0010f>

=================================================================

@FDDenny
Copy link

FDDenny commented Oct 22, 2021

We are currently experiencing the same issue in one of our applications that uses a Tabbed Page. We see the hang/freeze occur every time if we use a custom UINavigationControllerDelegate for the MoreNavigationController.Delegate. When we remove this portion of the platform specific render for iOS the hang no longer occurs but frequent crashing still occurs in the application related to #14750 and #14782

@jsuarezruiz jsuarezruiz added i/high Completely doesn't work, crashes, or is unusably slow, has no obvious workaround; occurs less often iOS 15 p/iOS 🍎 labels Oct 25, 2021
@jsuarezruiz jsuarezruiz added this to New in Triage via automation Oct 25, 2021
@jfversluis
Copy link
Member

@justin-loverme just to be clear, this also happens with pre-2196 versions right? We think it might be something that was introduced in iOS and not so much on our side. Which of course doesn't mean that we won't fix it :)

Are you maybe able to somehow provide a reproduction sample? At this moment we're unable to reproduce it ourselves which makes it harder to pinpoint the exact location and come up with a fix.

@justin-loverme
Copy link
Author

@jfversluis Correct, this happens in previous Xamarin.Forms versions and also occurs in our current production deployed app. I agree it appears to have been introduced on iOS 15 as in my testing, I cannot reproduce it on iOS 14.8.

Not sure I can get a sample project to reproduce it because the Calendar control is a licensed product, but I can see if I can simulate the issue.

@FDDenny
Copy link

FDDenny commented Oct 25, 2021

@justin-loverme are you using a custom UINavigationControllerDelegate for the MoreNavigationController.Delegate for in your iOS tabbed page render?

@jsuarezruiz jsuarezruiz moved this from New to Needs Info in Triage Oct 26, 2021
@jsuarezruiz jsuarezruiz added the s/needs-info ❓ A question has been asked that requires an answer before work can continue on this issue. label Oct 26, 2021
@jfversluis
Copy link
Member

jfversluis commented Oct 26, 2021

@FDDenny if you're able to provide us with a reproduction of that scenario that would help!

We have also found this one which seems to describe this

@justin-loverme
Copy link
Author

@FDDenny No, we are not using any custom navigation controls for the iOS project of the solution

@FDDenny
Copy link

FDDenny commented Oct 26, 2021

@jfversluis i was able to make a small sample project that recreates the issue. Just used the Getting started project that Xamarin provides and made modifications from there. In order to see the crash/hang you have to go back and forth between selecting items in the menu to the left in the application. It also seems to occur faster if you go into one of the tabbed "more" pages. This wont make it happen right away but it speeds up the time it took for me to see the issue. I was able to reproduces this every time so it should happen for you with in a short time of using the application. I was also able to see a crash at one point that gave me a new stack trace that i hadn't seen before but it still had the removeChildViewController portion in it. I will add that at the bottom of this as well.

There is a bit of extra fluff in the iOS Tabbed Page Render, but that allowed the issue to happen quicker just extra information for you. Also i was able to get this to happen on a simulator so there should be no worry about trying to have this work on an actual device.

I have created a public repo here if you would like to check it out through github otherwise here is the zip file of it.
iOS15HangCrashReprodection.zip
xamarin crash stack trace.txt

@FDDenny
Copy link

FDDenny commented Oct 26, 2021

@jsuarezruiz would you like me to comment the sample project on any of the other two tickets that seem to relate to this issue?

@jfversluis
Copy link
Member

@FDDenny great work! I will check this out, thank you so much for putting this together. No need to add it to the other issues as well :)

@chamons
Copy link

chamons commented Oct 27, 2021

I can reproduce with latest iOS / macios / XF library.

Stack trace on device:
https://gist.github.com/chamons/3d830d8a4a2bbfbf293f93c132caa534
Stack trace in sim:

(lldb) bt
* thread #1, name = 'tid_103', queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1a)
  * frame #0: 0x00000001190e93cb libobjc.A.dylib`objc_msgSend + 11
    frame #1: 0x000000012779c063 UIKitCore`-[UIViewController dealloc] + 955
    frame #2: 0x00000001010202c4 AwesomeApp.iOS`xamarin_invoke_objc_method_implementation(self=0x00007fca36d1f530, sel="release", xamarin_impl=(AwesomeApp.iOS`xamarin_release_trampoline at trampolines.m:687)) at trampolines.m:618:9
    frame #3: 0x0000000101020448 AwesomeApp.iOS`xamarin_release_trampoline(self=0x00007fca36d1f530, sel="release") at trampolines.m:716:2
    frame #4: 0x000000010b2724d1 CoreFoundation`-[__NSArrayI dealloc] + 72
    frame #5: 0x00000001191059f7 libobjc.A.dylib`objc_object::sidetable_release(bool, bool) + 177
    frame #6: 0x0000000127686c56 UIKitCore`-[UIMoreListController .cxx_destruct] + 60
    frame #7: 0x00000001190ecd7a libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8: 0x00000001190ff1f3 libobjc.A.dylib`objc_destructInstance + 64
    frame #9: 0x0000000119105187 libobjc.A.dylib`-[NSObject dealloc] + 21
    frame #10: 0x0000000127f8fb29 UIKitCore`-[UIResponder dealloc] + 145
    frame #11: 0x000000012779c1cf UIKitCore`-[UIViewController dealloc] + 1319
    frame #12: 0x00000001190ecd7a libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #13: 0x00000001190ff1f3 libobjc.A.dylib`objc_destructInstance + 64
    frame #14: 0x0000000119105187 libobjc.A.dylib`-[NSObject dealloc] + 21
    frame #15: 0x0000000127f8fb29 UIKitCore`-[UIResponder dealloc] + 145
    frame #16: 0x000000012779c1cf UIKitCore`-[UIViewController dealloc] + 1319
    frame #17: 0x00000001276abdd2 UIKitCore`-[UINavigationController dealloc] + 389
    frame #18: 0x000000010101d7e8 AwesomeApp.iOS`xamarin_release_managed_ref(self=0x00007fca37964600, user_type=false) at runtime.m:1931:2
    frame #19: 0x0000000160962524

@chamons
Copy link

chamons commented Oct 27, 2021

It looks like we're dealloc a (Xamarin_Forms_Platform_iOS_PageRenderer *) self = 0x00007fca36d1f530 that is already dead

I tried running zombie instruments on it and got nothing useful

@FDDenny
Copy link

FDDenny commented Oct 28, 2021

In our custom iOS Tabbed Render i overrode the Dispose() functionality and did not call base.Dispose() this no longer caused the crashing and hanging to occur in our application. Obviously this is not a permanent solution as this is causing memory leaks to occur and that is still not a good thing.

Extra information:
I also overrode the PageRender, and NavigationRender so nether of their disposes are called / call their base.Dispose() during the case of the crash. So this is coming only from the Tabbed Dispose call.

@FDDenny
Copy link

FDDenny commented Oct 29, 2021

For those looking to input a temporary solution this is what we did to minimize the issue. This is in our Custom iOS TabbedRender.cs file we are overriding the base.Dispose so it is not called.

protected override void Dispose(bool disposing)
{
    if (DeviceInfo.Version < new Version(15, 0) || TabBar.Items.Length <= 4)
    {
        base.Dispose(disposing);
    }
}

This allows the least amount of people to be effected by a bad practice memory leak that is caused by not properly disposing. This allows for longer use of the application before a "Out Of Memory" Exception is called and force closes the applications rather then what ever issue is currently occurring this does not fix the issue as there is still crashes in both cases but this at least give the user longer time in the application before a restart is required.

@FDDenny
Copy link

FDDenny commented Oct 29, 2021

@jsuarezruiz I see this is still under the "Needs Info" and "Unverified" tag is there anything else i can try and provide so this issue can be looked at more?

@justin-loverme
Copy link
Author

@jfversluis Is there any update on this issue? Same experiences for users devices updated to iOS 15.1

@jfversluis
Copy link
Member

As you can see from the comments by others on our team, we have done some investigation, but this issue seems a tougher one. And maybe even, like mentioned before: a bug, or at least a change in behavior on the iOS side.

So far not a lot of users seem to impacted by this (fortunately for us, unfortunately for you). If you need a fix asap, I would suggest trying to implement a fix/workaround for your app for now.

With not a lot of users impacted so far, we can't justify the time to dig in to this for hours on end. I understand this might not be what you want to hear and I'm sorry, but I think it's good to put it out there and manage expectations so that you can also explore other paths. We would be very interested to hear any results of your investigations that might help it fix on our side.

@iliketaiko
Copy link

Is there any progress on this item.
Facing same issue too. When the TabbedPage contains more than 5 page. And click on back button.
This issue happened.

@khedheri
Copy link

khedheri commented Dec 1, 2021

have the same issue , specially when the tabbar contain more then 5 tabs

@justin-loverme
Copy link
Author

@jfversluis @jsuarezruiz As you can see more occurrences of this issue is still happening. I attempted to add some overrides to Disposing, OnDisappearing, and destruction events. Like @khedheri mentioned, the appears to primarily happen when the TappedPage has more than 5 tabs and thus on iOS the 'more' section is created and the issue seems to happen when the back button is pressed while viewing that inner 'more' tab page. This is a pretty critical issue since we as developer's seem to have no way to resolve this with the page events we are able to override.

@jfversluis
Copy link
Member

@chamons @Redth is this something we can reprioritize?

@mrjavicho
Copy link

Run into this error today. XF (5.0.0.2337) project running on iOS 15.1.
In my case, I have a tabbed page with 3 tabs. One of them contains a webview.

At first, I thought the freeze/crash happened when navigating to another page, but, apparently, it happens eventually when moving around the tabbed pages.

@jfversluis do you have any update on this? you mentioned that for the time being people facing this error should try to fix it on their part, but I wouldn't know where to start.

Is this actually related to the number of pages? Maybe related to something else we are using like the webview I mentioned before or images/videos inside the child pages? Any hint about the nature of the error will be very useful.

@jfversluis
Copy link
Member

Hey @mrjavicho unfortunately no new info on this at the moment.

@simonhornak
Copy link

This issue is still present in iOS 15.4 and Xamarin.Forms 5.0.0.2337. It seems to happen when calling Dispose() in iOS TabbedRender, so somewhere in:

protected override void Dispose(bool disposing)
	{
		if (disposing)
		{
			Page.SendDisappearing();

			_tabBarAppearance?.Dispose();
			_tabBarAppearance = null;

			Tabbed.PropertyChanged -= OnPropertyChanged;
			Tabbed.PagesChanged -= OnPagesChanged;
			FinishedCustomizingViewControllers -= HandleFinishedCustomizingViewControllers;
		}

		base.Dispose(disposing);
	}

Workaround is:

  1. Override Dispose so it doesn't call base.Dispose() like this
[assembly: ExportRenderer(typeof(MyTabbedPage), typeof(MyTabbedPageRenderer))]
namespace MyXamarinApp.iOS.UI.Renderers
{
    public class MyTabbedPageRenderer : TabbedRenderer
    {
        protected override void Dispose(bool disposing)
        {
            //base.Dispose(disposing);
        }
    }
}

or
2. Implement DisposeEx extension method https://stackoverflow.com/a/27073456/4331976 and call Garbage Collector after calling DisposeEx like this.

[assembly: ExportRenderer(typeof(MyTabbedPage), typeof(MyTabbedPageRenderer))]
namespace MyXamarinApp.iOS.UI.Renderers
{
    public class MyTabbedPageRenderer : TabbedRenderer
    {
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (Element != null)
            {
                Element.PropertyChanged -= ElementOnPropertyChanged;
            }
            try
            {
                this.View?.DisposeEx();
                this.NativeView?.DisposeEx();
                this.ViewIfLoaded?.DisposeEx();

                this.View?.RemoveAndDisposeChildSubViews();
                this.NativeView?.RemoveAndDisposeChildSubViews();
                this.ViewIfLoaded?.RemoveAndDisposeChildSubViews();
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Failed to dispose MyTabbedPageRenderer:" + ex.Message);
            }

            GC.Collect();
        }
    }
}

Just implementing DisposeEx or just calling GC.Collect frequently doesn't overcome this problem. I have to use both.

Using both using DisposeEx or explicitly frequently calling GC.Collect independently seem to greatly reduce the frequency of this crash on their own.

When using both - DisposeEx and frequent explicit GC.Collect calls - app seems to work OK and not crash at all (even without overriding TabbedRender Dispose method).

Both of these workarounds are quite problematic so I would be glad if someone takes a look at this problem.

I can also confirm I started seeing this crash since upgrading to iOS 15 and I wasn't seeing it before.

@SoggyToastMan
Copy link

These crashes are increasing more as more users use iOS 15. I can confirm is has to do with the TabbedPage with the More option on iOS when disposing. For our app when the user enters a tabbed page, then hits back to a list and tries to interact with anything else is when it crashes. I tried using these work around options to not dispose of this page, but we see that the app eventually crashes. We have several views with this more option, and it happens 100% of the time on iOS 15+. Is there any update on this bug? Thank you

@SoggyToastMan
Copy link

Steps to reproduce:

  • Open a ListView page with list items
  • Tapping the list item will open a TabbedPage with enough tabs to have the More tab on iOS
  • Tap on the More tab
  • Hit back to list
  • Tap on any list item
  • Crash, sometimes freeze with SIGSEV

@alexmartinezm
Copy link

For those looking to input a temporary solution this is what we did to minimize the issue. This is in our Custom iOS TabbedRender.cs file we are overriding the base.Dispose so it is not called.

protected override void Dispose(bool disposing)
{
    if (DeviceInfo.Version < new Version(15, 0) || TabBar.Items.Length <= 4)
    {
        base.Dispose(disposing);
    }
}

This allows the least amount of people to be effected by a bad practice memory leak that is caused by not properly disposing. This allows for longer use of the application before a "Out Of Memory" Exception is called and force closes the applications rather then what ever issue is currently occurring this does not fix the issue as there is still crashes in both cases but this at least give the user longer time in the application before a restart is required.

I had to use the following method to get it working:

UIDevice.CurrentDevice.CheckSystemVersion(15, 0);

@TrsThomas
Copy link

TrsThomas commented Apr 1, 2022

Thank you @SoggyToastMan for your reply. In our case it's freezes rather than crashes, but we have been trying to reproduce this problem for a while and we couldn't quite figure it out until your reply!

We have now implemented the DisposeEx and GC.Collect as provided by @simonhornak. We no longer experience freezes when we're trying to reproduce the issue.

We can also confirm this started since users started upgrading to iOS15.

@alexmartinezm
Copy link

Thank you @SoggyToastMan for your reply. In our case it's freezes rather than crashes, but we have been trying to reproduce this problem for a while and we couldn't quite figure it out until your reply!

We have now implemented the DisposeEx and GC.Collect as provided by @simonhornak. We no longer experience freezes when we're trying to reproduce the issue.

We can also confirm this started since users started upgrading to iOS15.

Have you tried by commenting the Dispose method?

@TrsThomas
Copy link

TrsThomas commented Apr 1, 2022

Thank you @SoggyToastMan for your reply. In our case it's freezes rather than crashes, but we have been trying to reproduce this problem for a while and we couldn't quite figure it out until your reply!
We have now implemented the DisposeEx and GC.Collect as provided by @simonhornak. We no longer experience freezes when we're trying to reproduce the issue.
We can also confirm this started since users started upgrading to iOS15.

Have you tried by commenting the Dispose method?

We only tried workaround 2 and we have not tried commenting the Dispose method in that workaround.

@simonhornak
Copy link

@TrsThomas @alexmartinezm @SoggyToastMan
Me and my colleague came up with a workaround update that should be more stable than both Workaround 1 or Workaround 2 and doesn't need Garbage Collector Collect to be explicitly called - basically combine Workaround 1 and 2.

We deactivate base.Dispose() and implement DisposeEx instead. This probably causes a small memory leak (TabbedPage not getting disposed), but thanks to using DisposeEx, this memory leak should be very small - DisposeEx is disposing all Views and Subviews associated with the TabbedPage and only the "empty" TabbedPage isn't disposed. So this should (?) dispose most of the associated resources anyways and "should" be more stable than each workaround on its own.

[assembly: ExportRenderer(typeof(MyTabbedPage), typeof(MyTabbedPageRenderer))]
namespace MyApp.Platform.iOS.UI.Renderers
{
    public class MyTabbedPageRenderer : TabbedRenderer
    {
        private bool _disposed;

        protected override void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }
            _disposed = true;

            if (disposing)
            {
                try
                {
                    View?.DisposeEx();
                    NativeView?.DisposeEx();
                    ViewIfLoaded?.DisposeEx();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"Failed to dispose MyTabbedPageRenderer: {ex.Message}");
                }
            }
            // Don't call base Dispose (causes native crash)
            // base.Dispose(disposing);
        }
    }
}

@SoggyToastMan
Copy link

@TrsThomas @alexmartinezm @SoggyToastMan Me and my colleague came up with a workaround update that should be more stable than both Workaround 1 or Workaround 2 and doesn't need Garbage Collector Collect to be explicitly called - basically combine Workaround 1 and 2.

We deactivate base.Dispose() and implement DisposeEx instead. This probably causes a small memory leak (TabbedPage not getting disposed), but thanks to using DisposeEx, this memory leak should be very small - DisposeEx is disposing all Views and Subviews associated with the TabbedPage and only the "empty" TabbedPage isn't disposed. So this should (?) dispose most of the associated resources anyways and "should" be more stable than each workaround on its own.

[assembly: ExportRenderer(typeof(MyTabbedPage), typeof(MyTabbedPageRenderer))]
namespace MyApp.Platform.iOS.UI.Renderers
{
    public class MyTabbedPageRenderer : TabbedRenderer
    {
        private bool _disposed;

        protected override void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }
            _disposed = true;

            if (disposing)
            {
                try
                {
                    View?.DisposeEx();
                    NativeView?.DisposeEx();
                    ViewIfLoaded?.DisposeEx();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"Failed to dispose MyTabbedPageRenderer: {ex.Message}");
                }
            }
            // Don't call base Dispose (causes native crash)
            // base.Dispose(disposing);
        }
    }
}

Thank you for posting this. So far this seems to be the best workaround for the bug.

@SoggyToastMan
Copy link

@TrsThomas @alexmartinezm @SoggyToastMan Me and my colleague came up with a workaround update that should be more stable than both Workaround 1 or Workaround 2 and doesn't need Garbage Collector Collect to be explicitly called - basically combine Workaround 1 and 2.
We deactivate base.Dispose() and implement DisposeEx instead. This probably causes a small memory leak (TabbedPage not getting disposed), but thanks to using DisposeEx, this memory leak should be very small - DisposeEx is disposing all Views and Subviews associated with the TabbedPage and only the "empty" TabbedPage isn't disposed. So this should (?) dispose most of the associated resources anyways and "should" be more stable than each workaround on its own.

[assembly: ExportRenderer(typeof(MyTabbedPage), typeof(MyTabbedPageRenderer))]
namespace MyApp.Platform.iOS.UI.Renderers
{
    public class MyTabbedPageRenderer : TabbedRenderer
    {
        private bool _disposed;

        protected override void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }
            _disposed = true;

            if (disposing)
            {
                try
                {
                    View?.DisposeEx();
                    NativeView?.DisposeEx();
                    ViewIfLoaded?.DisposeEx();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"Failed to dispose MyTabbedPageRenderer: {ex.Message}");
                }
            }
            // Don't call base Dispose (causes native crash)
            // base.Dispose(disposing);
        }
    }
}

Thank you for posting this. So far this seems to be the best workaround for the bug.

After about 10 minutes of usage we are noticing the crash still happening =(

@TrsThomas
Copy link

@jfversluis Is there any news yet or an update on this issue?

@iliketaiko
Copy link

Also expecting new from this item...

@TrsThomas
Copy link

@jfversluis Is there any news yet or an update on this issue?

@paddymccallan-izon
Copy link

@jfversluis Any update on this?

@dhewitson
Copy link

We're still seeing this using iOS 16.4. Is there any update other than the workarounds?

@paddymccallan-izon
Copy link

would upgrading to MAUI fix this issue?

@pme442
Copy link

pme442 commented Feb 22, 2024

Any updates on this?

@paddymccallan-izon
Copy link

Any updates on this?

@pme442 bit the bullet and upgraded to .net maui which sorted this issue

@mcyenikoylu
Copy link

I'm having this issue on a .NET 8 MAUI that I just created.

I create a new MAUI project and set the ContentPage type to TabbedPage on the MainPage page. I'm getting the memory error.

When I run the tabbed project in the MAUI Sample projects on my computer, I do not receive any errors.

It seems that it is not possible to start a new project with TabbedPage.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
i/high Completely doesn't work, crashes, or is unusably slow, has no obvious workaround; occurs less often iOS 15 p/iOS 🍎 s/needs-info ❓ A question has been asked that requires an answer before work can continue on this issue. s/unverified New report that has yet to be verified t/bug 🐛
Projects
Triage
  
Needs Info
Development

No branches or pull requests