Xamarin iOS app only crashes when opened through TestFlight

ParadoxParadox CAMember ✭✭

I'm facing a strange error. The app works perfectly fine in Debug and Ad-Hoc etc. When I upload the app to TestFlight, it crashes when you download the app and hit 'Open'. The weird thing is that if you open the app just through the OS, everything works as expected. I've done a lot of digging around and suspect it may be something to do with the FinishedLaunching Event and my check for the RemoteNotificationKey...but I really can't be sure. Do I need a special condition for handling the launch through TestFlight?

I've symbolicated the crash log and pasted it below (just the first section which seems relevant). Any help would be greatly appreciated.


Date/Time: 2017-03-06 22:45:00.8870 -0500
Launch Time: 2017-03-06 22:45:00.0333 -0500
OS Version: iPhone OS 10.0.2 (14A456)
Report Version: 104

Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0

Application Specific Information:
abort() called

Filtered syslog:
None found

Thread 0 name: tid_a07 Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x000000018f892014 pthread_kill + 8
1 libsystem_pthread.dylib 0x000000018f959460 pthread_kill + 112
2 libsystem_c.dylib 0x000000018f8063f4 abort + 140
3 GlobalMeetiOS 0x00000001007e15fc mono_handle_native_sigsegv (mini-exceptions.c:2420)
4 libsystem_platform.dylib 0x000000018f953348 _sigtramp + 52
5 libsystem_pthread.dylib 0x000000018f959460 pthread_kill + 112
6 libsystem_c.dylib 0x000000018f8063f4 abort + 140
7 GlobalMeetiOS 0x00000001008c9530 print_all_exceptions(MonoObject*) (runtime.m:997)
8 GlobalMeetiOS 0x00000001007e1d34 mono_invoke_unhandled_exception_hook (mini-exceptions.c:2873)
9 GlobalMeetiOS 0x00000001007e1290 mono_handle_exception_internal (mini-exceptions.c:1798)
10 GlobalMeetiOS 0x00000001007e0370 mono_handle_exception (mini-exceptions.c:2027)
11 GlobalMeetiOS 0x00000001007d8e6c mono_arm_throw_exception (exceptions-arm64.c:390)
12 GlobalMeetiOS 0x0000000100b6d7e8 throw_exception + 168
13 GlobalMeetiOS 0x0000000101469940 Xamarin_Forms_Platform_iOS_Xamarin_Forms_Platform_iOS_FormsApplicationDelegate_OnActivated_UIKit_UIApplication + 0
14 GlobalMeetiOS 0x00000001008ced50 GlobalMeetiOS_GlobalMeet_iOS_AppDelegate_FinishedLaunching_UIKit_UIApplication_Foundation_NSDictionary + 412
15 GlobalMeetiOS 0x0000000100b4eb64 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 244
16 GlobalMeetiOS 0x00000001007ee290 mono_jit_runtime_invoke (mini-runtime.c:2524)
17 GlobalMeetiOS 0x000000010084a524 do_runtime_invoke (object.c:2809)
18 GlobalMeetiOS 0x000000010084a480 mono_runtime_invoke (object.c:2967)
19 GlobalMeetiOS 0x00000001019e17b4 native_to_managed_trampoline_6(objc_object*, objc_selector*, _MonoMethod**, UIApplication*, NSDictionary*, char const*, char const*, char const*, char const*) (registrar.m:250)
20 GlobalMeetiOS 0x00000001019e1f4c -[AppDelegate application:didFinishLaunchingWithOptions:] (registrar.m:6765)
21 UIKit 0x000000019677f42c -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 400
22 UIKit 0x000000019698fb70 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 3524
23 UIKit 0x00000001969958e0 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1656
24 UIKit 0x00000001969aa080 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke.3134 + 48
25 UIKit 0x00000001969928c4 -[UIApplication workspaceDidEndTransaction:] + 168
26 FrontBoardServices 0x00000001924658bc __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK
+ 36
27 FrontBoardServices 0x0000000192465728 -[FBSSerialQueue _performNext] + 176
28 FrontBoardServices 0x0000000192465ad0 -[FBSSerialQueue _performNextFromRunLoopSource] + 56
29 CoreFoundation 0x0000000190872278 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 24
30 CoreFoundation 0x0000000190871bc0 CFRunLoopDoSources0 + 524
31 CoreFoundation 0x000000019086f7c0 __CFRunLoopRun + 804
32 CoreFoundation 0x000000019079e048 CFRunLoopRunSpecific + 444
33 UIKit 0x00000001967785dc -[UIApplication _run] + 608
34 UIKit 0x0000000196773360 UIApplicationMain + 208
35 GlobalMeetiOS 0x0000000100c5fae4 wrapper_managed_to_native_UIKit_UIApplication_UIApplicationMain_int_string___intptr_intptr (/:1)
36 GlobalMeetiOS 0x0000000100be433c Xamarin_iOS_UIKit_UIApplication_Main_string___string_string (UIApplication.cs:63)
37 GlobalMeetiOS 0x00000001008ceb98 GlobalMeetiOS_GlobalMeet_iOS_Application_Main_string
+ 28
38 GlobalMeetiOS 0x0000000100b4eb64 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 244
39 GlobalMeetiOS 0x00000001007ee290 mono_jit_runtime_invoke (mini-runtime.c:2524)
40 GlobalMeetiOS 0x000000010084a524 do_runtime_invoke (object.c:2809)
41 GlobalMeetiOS 0x000000010084c548 mono_runtime_exec_main (object.c:4585)
42 GlobalMeetiOS 0x000000010084c164 mono_runtime_run_main (object.c:4134)
43 GlobalMeetiOS 0x00000001007d868c mono_jit_exec (driver.g.c:1048)
44 GlobalMeetiOS 0x00000001008cd694 xamarin_main (monotouch-main.m:487)
45 GlobalMeetiOS 0x0000000101a02ef8 main (main.arm64.m:131)
46 libdyld.dylib 0x000000018f7805b8 start + 4

Thread 1:
0 libsystem_kernel.dylib 0x000000018f892a88 __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x000000018f95536c _pthread_wqthread + 1452
2 libsystem_pthread.dylib 0x000000018f954db4 start_wqthread + 4

Thread 2:
0 libsystem_kernel.dylib 0x000000018f892a88 __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x000000018f955188 _pthread_wqthread + 968
2 libsystem_pthread.dylib 0x000000018f954db4 start_wqthread + 4

Thread 3:
0 libsystem_pthread.dylib 0x000000018f954db0 start_wqthread + 0

Tagged:

Best Answer

  • ParadoxParadox CA ✭✭
    edited March 2017 Accepted Answer

    I figured it out. It turned out to be a problem with the launchOptions parameter in the FinishedLaunching event. Again, strangely this only happened when opening the app from TestFlight. I guess after downloading the app and hitting the 'Open' button from TestFlight, it caused the launchOptions parameter to have some value. However, this caused some strange behaviour in the rest of my code.

    The code that specifically broke was the check to see whether launchOptions was null. I was able to pinpoint the source of the crash and simply having -> if (launchOptions!=null) {...rest of code here...} was causing the crash.

    I even took out all the code inside that code block and the app still crashed. Then, I removed the null check and the app no longer crashed on opening from TestFlight. Of course, now it would crash when simply opening it the regular way because I was checking launchOption keys without first explicitly making sure launchOptions wasn't null.

    If someone from Xamarin could explain this, it would be very helpful.

    The fix was to implement a way to handle exceptions thrown; this article helped me out with that:
    https://forums.xamarin.com/discussion/931/how-to-prevent-ios-crash-reporters-from-crashing-monotouch-apps

    From the above example, I essentially wrapped the offending code inside that method mentioned ...and everything worked like a charm!

    Hopefully, this will help someone else out struggling with the same issue.

Answers

  • ParadoxParadox CAMember ✭✭
    edited March 2017 Accepted Answer

    I figured it out. It turned out to be a problem with the launchOptions parameter in the FinishedLaunching event. Again, strangely this only happened when opening the app from TestFlight. I guess after downloading the app and hitting the 'Open' button from TestFlight, it caused the launchOptions parameter to have some value. However, this caused some strange behaviour in the rest of my code.

    The code that specifically broke was the check to see whether launchOptions was null. I was able to pinpoint the source of the crash and simply having -> if (launchOptions!=null) {...rest of code here...} was causing the crash.

    I even took out all the code inside that code block and the app still crashed. Then, I removed the null check and the app no longer crashed on opening from TestFlight. Of course, now it would crash when simply opening it the regular way because I was checking launchOption keys without first explicitly making sure launchOptions wasn't null.

    If someone from Xamarin could explain this, it would be very helpful.

    The fix was to implement a way to handle exceptions thrown; this article helped me out with that:
    https://forums.xamarin.com/discussion/931/how-to-prevent-ios-crash-reporters-from-crashing-monotouch-apps

    From the above example, I essentially wrapped the offending code inside that method mentioned ...and everything worked like a charm!

    Hopefully, this will help someone else out struggling with the same issue.

  • JamesFormicaJamesFormica AUMember

    @Paradox I currently am experiencing this error in TestFlight. I'm not too sure which method you wrapped your code in. I've read the linked post but im still unsure. Can you please show me a code snippet of how you fixed it?

    Any help is appreciated :)

    Thanks

  • ParadoxParadox CAMember ✭✭
    edited June 2017

    Hi James,

    Sure thing. The code is in the AppDelegate class. The main section is the sigaction and EnableCrashReporting code.

    I've posted the relevant portion of my code below.

    [Register("AppDelegate")]
        public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
        {
            private GlobalMeet.App _pclApp;
    
            [DllImport("libc")]
            private static extern int sigaction(Signal sig, IntPtr act, IntPtr oact);
    
            enum Signal
            {
                SIGBUS = 10,
                SIGSEGV = 11
            }
    
            private void EnableCrashReporting(NSDictionary options)
            {
                IntPtr sigbus = Marshal.AllocHGlobal(512);
                IntPtr sigsegv = Marshal.AllocHGlobal(512);
    
                // Store Mono SIGSEGV and SIGBUS handlers
                sigaction(Signal.SIGBUS, IntPtr.Zero, sigbus);
                sigaction(Signal.SIGSEGV, IntPtr.Zero, sigsegv);
    
                // Enable crash reporting libraries
                CheckLaunchOptions(options);
    
                // Restore Mono SIGSEGV and SIGBUS handlers            
                sigaction(Signal.SIGBUS, sigbus, IntPtr.Zero);
                sigaction(Signal.SIGSEGV, sigsegv, IntPtr.Zero);
            }
    
            private void CheckLaunchOptions(NSDictionary launchOptions)
            {
                if (launchOptions != null)
                {
                    if (launchOptions.ContainsKey(UIApplication.LaunchOptionsRemoteNotificationKey))
                    {
                        NSDictionary userInfo = (NSDictionary)launchOptions[UIApplication.LaunchOptionsRemoteNotificationKey];
                        if (userInfo != null)
                        {
                            var parameters = ProcessNotification(userInfo, true);
                            _pclApp = new App(parameters);
    
    
                        }
                    }
                    if (launchOptions.ContainsKey(UIApplication.LaunchOptionsUrlKey))
                    {
                        if (_pclApp == null)
                        {
                            _pclApp = new App();
    
                        }
    
                    }
    
                }
            }
    
            //
            // This method is invoked when the application has loaded and is ready to run. In this 
            // method you should instantiate the window, load the UI into it and then make the window
            // visible.
            //
            // You have 17 seconds to return from this method, or iOS will terminate your application.
            //
            public override bool FinishedLaunching(UIApplication uiApplication, NSDictionary launchOptions)
            {
    
                UIApplication.SharedApplication.IdleTimerDisabled = true;
                //Consider inizializing before application initialization, if using any CrossPushNotification method during application initialization.
                CrossPushNotification.Initialize<CrossPushNotificationListener>();
    
                global::Xamarin.Forms.Forms.Init();
    
    
                CheckLaunchOptions(launchOptions);
                if (_pclApp == null) _pclApp = new App();
                LoadApplication(_pclApp);
    
                return base.FinishedLaunching(uiApplication, launchOptions);
            }
    
  • CameronKlenkCameronKlenk USMember ✭✭

    @Paradox I tried your solution, but it did not work for me. I am having the same issue. I'll attach my crash log too.

    Thanks.

  • ManoNagarajanManoNagarajan USMember ✭✭
    edited January 2018

    @Paradox Im also have same issue. any workaround?

    what is ProcessNotification?

  • ParadoxParadox CAMember ✭✭

    @ManojkumarMali Don't worry about ProcessNotification - it's actually just my own method to do something when there's a notification.

    It's hard to say why it's not working for you but it's important that you check your launchOptions, because when launched from TestFlight (or eventually the App Store), iOS fills out the launchOptions parameter and you have to make sure you handle it correctly in case it's null. At least that was the issue for me.

Sign In or Register to comment.