xamarin / xamarin-macios

.NET for iOS, Mac Catalyst, macOS, and tvOS provide open-source bindings of the Apple SDKs for use with .NET managed languages such as C#
Other
2.45k stars 511 forks source link

.NET MAUI App Crashes in Background on iOS Release #20769

Closed phillippschmedt closed 1 month ago

phillippschmedt commented 3 months ago

Hi there,

I attached two crash logs I see on my iPhone 13 running 17.5.1.

I run the app in release mode without any special settings. The crash happens when my app receives a (silent) push notification. I first assumed this was because my app was taking too much time loading data when the silent push is received, but even when I remove all custom code that handles the push the crash will occure.

Exception Type: EXC_CRASH (SIGKILL) Exception Codes: 0x0000000000000000, 0x0000000000000000 Termination Reason: FRONTBOARD 2343432205 <RBSTerminateContext| domain:10 code:0x8BADF00D explanation:scene-create watchdog transgression: app<de.myapp.xxx(FA79BDA1-53CA-4CAA-81B7-CAB5DBD4C529)>:56077 exhausted CPU time allowance of 3.23 seconds ProcessVisibility: Background ProcessState: Running WatchdogEvent: scene-create WatchdogVisibility: Background WatchdogCPUStatistics: ( "Elapsed total CPU time (seconds): 5.230 (user 3.520, system 1.710), 26% CPU", "Elapsed application CPU time (seconds): 3.749, 19% CPU" ) reportType:CrashLog maxTerminationResistance:Interactive>

I can't reproduce it with a debug build locally.

myapp-2024-06-24-020442.txt myapp-2024-06-24-130135.txt

Could you please have a look at the crash reports? Also let me know if there is any other information I can provide.

Thanks a lot

rolfbjarne commented 3 months ago

Can you add this to your csproj and try again?

<PropertyGroup>
    <NoSymbolStrip>true</NoSymbolStrip>
</PropertyGroup>

This should produce a better stack trace in crash reports (methods will be symbolicated instead of showing up as only memory addresses), which will make it much easier to figure out what's going on.

phillippschmedt commented 3 months ago

Hi @rolfbjarne thanks a lot for trying to help me. It took me a while to get it symbolicated. For some reason using <NoSymbolStrip>true</NoSymbolStrip> would not give me the symbols. Eventually I had to use the dsym file.

Here is a symbolicated log of the crash myapp2024-06-26-220557_symbolicated.txt

rolfbjarne commented 3 months ago

You're correct that the app is crashing because it's taking too long:

exhausted CPU time allowance of 3.21 seconds

The stack trace is strange though, in that it's completely normal, it's not hanging nor waiting for something:

Thread 0 name:  tid_103 Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   CoreFoundation                         0x19a8f9590 __CFBinaryPlistGetTopLevelInfo + 440
1   Foundation                             0x1997eecfc -[_NSBPlistMappedData initWithFileURL:error:] + 156
2   Foundation                             0x1997eebe8 __NSCreateBPlistMappedDataFromURL + 88
3   CoreFoundation                         0x19a97b618 _CFBundleMapBPlistFile + 124
4   CoreFoundation                         0x19a92d7d8 _CFBundleGetStringsSources + 360
5   CoreFoundation                         0x19a8ceaf0 _copyStringTable + 612
6   CoreFoundation                         0x19a8cba90 _CFBundleCopyLocalizedStringForLocalizationTableURLAndMarkdownOption + 204
7   Foundation                             0x199780a80 -[NSBundle localizedStringForKey:value:table:] + 56
8   UIKitCore                              0x19ccbde50 _UINSLocalizedStringWithDefaultValue + 72
9   UIKitCore                              0x19d060d64 __42+[UIMenu(DefaultMenus) _defaultMenuTitles]_block_invoke + 128
10  libdispatch.dylib                      0x1a27a9dd4 _dispatch_client_callout + 20
11  libdispatch.dylib                      0x1a27ab654 _dispatch_once_callout + 32
12  UIKitCore                              0x19ccbbebc +[UIMenu(DefaultMenus) _defaultMenuTitles] + 80
13  UIKitCore                              0x19ccbbd9c +[UIMenu(DefaultMenus) _defaultMenuWithIdentifier:options:children:] + 68
14  UIKitCore                              0x19ccbaf08 -[_UIMainMenuSystem _init] + 108
15  UIKitCore                              0x19cbeac44 __34+[_UIMainMenuSystem _sharedSystem]_block_invoke + 24
16  libdispatch.dylib                      0x1a27a9dd4 _dispatch_client_callout + 20
17  libdispatch.dylib                      0x1a27ab654 _dispatch_once_callout + 32
18  UIKitCore                              0x19d038314 +[_UIMainMenuSystem _sharedSystem] + 156
19  myApp                          0x107b4cc80 xamarin_dyn_objc_msgSend (in myApp) + 160 + 82758784
20  myApp                          0x103a32ce0 wrapper_managed_to_native_ObjCRuntime_Messaging_NativeHandle_objc_msgSend_intptr_intptr (in myApp) + 160 + 14494944
21  myApp                          0x107aad6fc Microsoft_iOS_UIKit_UIMenuSystem_get_MainSystem (in myApp) (UIMenuSystem.g.cs:131) + 82106108
22  myApp                          0x107ddcd3c mono_jit_runtime_invoke (in myApp) (mini-runtime.c:3637) + 85445948
23  myApp                          0x107d89990 mono_runtime_try_invoke (in myApp) (object.c:2733) + 85105040
24  myApp                          0x107d8c6b0 mono_runtime_invoke (in myApp) (object.c:2659) + 85116592
25  myApp                          0x107eb96f8 native_to_managed_trampoline_4(objc_object*, objc_selector*, _MonoMethod**, objc_object*, objc_object*, unsigned int) (in myApp) (registrar.mm:217) + 86349560
26  myApp                          0x107ebc644 -[AppDelegate application:didFinishLaunchingWithOptions:] (in myApp) (registrar.mm:9190) + 86361668
[...]

Do you get the exact same stack trace every time (this would be even stranger)? Or is it doing something else each time (which I'd expect if the app is doing a lot of processing)?

See also https://developer.apple.com/documentation/xcode/addressing-watchdog-terminations

phillippschmedt commented 3 months ago

Some points:

While I must confess that I do not understand most of the stacktrace, I wonder why there is a lot of UICoreKit in the Stacktrace when the app is in the background and received a silent push. Is this normal?

rolfbjarne commented 3 months ago

I wonder why there is a lot of UICoreKit in the Stacktrace when the app is in the background and received a silent push. Is this normal?

That's actually interesting.

Your crash report says "explanation:scene-create", Apple's documentation about "scene-create" is: "When scene-create appears in the Termination Description, the app didn’t render the first frame of its UI to the screen within the allowed wall clock time."

Sounds like iOS thinks your app should show a UI, and your app thinks it's just a silent notification, so there's nothing to show.

Note that iOS calls UIApplicationDelegate.DidFinishLaunching (frame 26), where it looks like you call UIMenuSystem.MainSystem:

21  myApp                          0x107aad6fc Microsoft_iOS_UIKit_UIMenuSystem_get_MainSystem (in myApp) (UIMenuSystem.g.cs:131) + 82106108
22  myApp                          0x107ddcd3c mono_jit_runtime_invoke (in myApp) (mini-runtime.c:3637) + 85445948
23  myApp                          0x107d89990 mono_runtime_try_invoke (in myApp) (object.c:2733) + 85105040
24  myApp                          0x107d8c6b0 mono_runtime_invoke (in myApp) (object.c:2659) + 85116592
25  myApp                          0x107eb96f8 native_to_managed_trampoline_4(objc_object*, objc_selector*, _MonoMethod**, objc_object*, objc_object*, unsigned int) (in myApp) (registrar.mm:217) + 86349560
26  myApp                          0x107ebc644 -[AppDelegate application:didFinishLaunchingWithOptions:] (in myApp) (registrar.mm:9190) + 86361668

Maybe check in DidFinishLaunching to see which options are passed, and potentially not do anything if it's due to a notification?

phillippschmedt commented 3 months ago

I am waiting for the result of the changes to DidFinishLaunching. In the meantime I got another crash that looks quite different to me. Again this happens around the full-hour, this is where we send the silent pushes.

myApp-2024-06-27-100234_symbolicated.txt

rolfbjarne commented 3 months ago

I am waiting for the result of the changes to DidFinishLaunching. In the meantime I got another crash that looks quite different to me. Again this happens around the full-hour, this is where we send the silent pushes.

myApp-2024-06-27-100234_symbolicated.txt

That's in our startup logic, but it's strange, because this typically takes milliseconds (it happens on every launch for every app).

Does this happen on multiple devices, or just one?

phillippschmedt commented 3 months ago

I am waiting for the result of the changes to DidFinishLaunching. In the meantime I got another crash that looks quite different to me. Again this happens around the full-hour, this is where we send the silent pushes. myApp-2024-06-27-100234_symbolicated.txt

That's in our startup logic, but it's strange, because this typically takes milliseconds (it happens on every launch for every app).

Does this happen on multiple devices, or just one?

We have seen the crashes on at least 3 different devices. Two iPhone XR and one iPhone 13. It happens every few hours on those devices. Will get at least a crash a day, sometimes multiple. Always around the hour where it should receive the push notification. While we have other devices that never crash, one specific device would be an iPhone 14.

The only way to get those crash reports right now for me is to get them directly from the device. I do not get stacktraces in appcenter or xcode/testflight crashes.

rolfbjarne commented 3 months ago

I am waiting for the result of the changes to DidFinishLaunching. In the meantime I got another crash that looks quite different to me. Again this happens around the full-hour, this is where we send the silent pushes. myApp-2024-06-27-100234_symbolicated.txt

That's in our startup logic, but it's strange, because this typically takes milliseconds (it happens on every launch for every app). Does this happen on multiple devices, or just one?

We have seen the crashes on at least 3 different devices. Two iPhone XR and one iPhone 13. It happens every few hours on those devices. Will get at least a crash a day, sometimes multiple. Always around the hour where it should receive the push notification. While we have other devices that never crash, one specific device would be an iPhone 14.

The only way to get those crash reports right now for me is to get them directly from the device. I do not get stacktraces in appcenter or xcode/testflight crashes.

This is really puzzling. I've never seen a watchdog termination this early in the process startup. Do you use any third-party native libraries/frameworks? In theory they can have initializers that would run before our main method, and if they take a long time to run, it could explain this.

Otherwise my suggestion would be to collect as many crash reports as you can, and then investigate to see if there's something common about them.

phillippschmedt commented 3 months ago

I changed DidFinishedLaunching to do nothing when it's gets called by the push notification. That made no difference. Crash still persists.

We indeed use a bunch of libraries. I will do some more investigation and collect more crash reports and will report back once I find anything new. Thanks a lot for your help so far.

phillippschmedt commented 2 months ago

@rolfbjarne I have another two crash reports, but I don't feel like they provide new insights. myApp-2024-07-18-120045_symbolicated.txt myApp2024-07-23-114651_symbolicated.txt

Could you maybe try to help me with the following questions:

  1. I am currently using the default release configurations. Is there any flags that could potentially increase the performance here and make it less likely to run into the timeout? My current observation is that it's more likely to crash on older devices than on newer ones.
  2. We didn't see this crash in our xamarin app and this app is a 100% port of that app with only minor changes to our code. Is there anything new that MAUI does when the app wakes up from the background?

Thanks a lot!

phillippschmedt commented 2 months ago

More crash reports: myApp-2024-07-29-120225_symbolicated.txt myApp-2024-07-29-140157_symbolicated.txt myApp-2024-07-29-130425_symbolicated.txt myApp-2024-07-29-150203_symbolicated.txt

phillippschmedt commented 2 months ago

@rolfbjarne Can you please reopen this issue? Thank you!

rolfbjarne commented 1 month ago

myApp-2024-07-29-150203_symbolicated.txt

[...]
16  UIKitCore                              0x1a424fa80 -[UIViewController view] + 24
17  myApp                          0x1076335e0 xamarin_dyn_objc_msgSendSuper (in myApp) + 164 + 82490848
18  myApp                          0x10354db30 wrapper_managed_to_native_ObjCRuntime_Messaging_NativeHandle_objc_msgSendSuper_intptr_intptr (in myApp) + 160 + 14441264
19  myApp                          0x107585380 Microsoft_iOS_UIKit_UIViewController_get_View (in myApp) (UIViewController.g.cs:3293) + 81777536
20  myApp                          0x1078c358c mono_jit_runtime_invoke (in myApp) (mini-runtime.c:3637) + 85177740
21  myApp                          0x1078701e0 mono_runtime_try_invoke (in myApp) (object.c:2733) + 84836832
22  myApp                          0x107872f00 mono_runtime_invoke (in myApp) (object.c:2659) + 84848384
23  myApp                          0x107931fe8 native_to_managed_trampoline_3(objc_object*, objc_selector*, _MonoMethod**, objc_object*, objc_object*, unsigned int) (in myApp) (registrar.mm:172) + 85630952
24  myApp                          0x10793211c -[Microsoft_Maui_MauiUIApplicationDelegate application:didFinishLaunchingWithOptions:] (in myApp) (registrar.mm:8649) + 85631260
[...]

If this is the app waking up due to a silent push, why is the app doing UI stuff (calling UIViewController.View)?

myApp-2024-07-29-130425_symbolicated.txt

16  myApp                          0x1064ab160 myApp_myApp_Services_Authentication_AuthenticationService_bnt (in myApp) (<unknown>:0) + 25899360
17  myApp                          0x1064aa57c myApp_myApp_Services_Authentication_AuthenticationService_LoginByBiometricAsync (in myApp) (<unknown>:0) + 25896316
[...]

Biometric logic requires user interaction, so why is this happening during a silent push?

myApp-2024-07-29-140157_symbolicated.txt

[...]
57  UIKitCore                              0x1a424fa80 -[UIViewController view] + 24
58  myApp                          0x107bab5e0 xamarin_dyn_objc_msgSendSuper (in myApp) + 164 + 82490848
59  myApp                          0x103ac5b30 wrapper_managed_to_native_ObjCRuntime_Messaging_NativeHandle_objc_msgSendSuper_intptr_intptr (in myApp) + 160 + 14441264
60  myApp                          0x107afd380 Microsoft_iOS_UIKit_UIViewController_get_View (in myApp) (UIViewController.g.cs:3293) + 81777536
61  myApp                          0x107e3b58c mono_jit_runtime_invoke (in myApp) (mini-runtime.c:3637) + 85177740
62  myApp                          0x107de81e0 mono_runtime_try_invoke (in myApp) (object.c:2733) + 84836832
63  myApp                          0x107deaf00 mono_runtime_invoke (in myApp) (object.c:2659) + 84848384
64  myApp                          0x107ea9fe8 native_to_managed_trampoline_3(objc_object*, objc_selector*, _MonoMethod**, objc_object*, objc_object*, unsigned int) (in myApp) (registrar.mm:172) + 85630952
65  myApp                          0x107eaa11c -[Microsoft_Maui_MauiUIApplicationDelegate application:didFinishLaunchingWithOptions:] (in myApp) (registrar.mm:8649) + 85631260
[...]

Same as the first stack trace snippet: looks like the app is loading UI (in particular the end of this stack trace is the app loading images from disk)

  1. I am currently using the default release configurations. Is there any flags that could potentially increase the performance here and make it less likely to run into the timeout? My current observation is that it's more likely to crash on older devices than on newer ones.

You can try adding this to your csproj:

<PropertyGroup>
    <MtouchExtraArgs>--require-pinvoke-wrappers=true</MtouchExtraArgs>
</PropertyGroup>

It will make the transition from C# to native code faster, at the expense of a bigger app.

  1. We didn't see this crash in our xamarin app and this app is a 100% port of that app with only minor changes to our code. Is there anything new that MAUI does when the app wakes up from the background?

No, nothing has changes with regards to waking up from the background.

phillippschmedt commented 1 month ago

@rolfbjarne Thank you. Unfortunately I can't answer any of your questions. I do not know why MAUI/.NET iOS/iOS is doing these things on the background when the push is received. It might be that SOME of the crash reports are not related to the push, because I don't know which ones are from pushes and which ones are crashing for other reasons. My only way to believe that it's the push notification is that: 1) We see a lot less crashes when we completely disable push notifications 2) many of the crashes are happening around the full hour, which is the time where we send the push notifications.

We have develop multiple xamarin apps and have barely any issues with crashes. On maui we see a lot more crashes and most of them are of the type I attached to this ticket.

My last hope now is to try to replicate this in a maui sample app with no custom code at all.

rolfbjarne commented 1 month ago

My last hope now is to try to replicate this in a maui sample app with no custom code at all.

That's a good idea to try.

Did you also try my suggestion from my previous comment, adding this to the csproj:

<PropertyGroup>
    <MtouchExtraArgs>--require-pinvoke-wrappers=true</MtouchExtraArgs>
</PropertyGroup>
microsoft-github-policy-service[bot] commented 1 month ago

Hi @phillippschmedt. Due to inactivity, we will be closing this issue. Please feel free to re-open this issue if the issue persists. For enhanced visibility, if over 7 days have passed, please open a new issue and link this issue there. Thank you.