Forum Xamarin.iOS
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

How to Get PLCrashReporter based frameworks to report .NET exceptions (e.g. HockeyApp)

I wanted to share a snippet of useful code for getting crash reports that include nicer .NET exception traces out of Xamarin.iOS apps. Here is the code which you can use

    {    
        ... whatever other exception set up you have ...

        AppDomain.CurrentDomain.UnhandledException +=
            (sender, args) => ConvertToNsExceptionAndAbort(args.ExceptionObject);
        TaskScheduler.UnobservedTaskException += (sender, args) => ConvertToNsExceptionAndAbort(args.Exception);
        ExceptionSupport.UncaughtTaskExceptionHandler = ConvertToNsExceptionAndAbort;
    }

    [DllImport(MonoTouch.Constants.FoundationLibrary, EntryPoint = "NSGetUncaughtExceptionHandler")]
    private static extern IntPtr NSGetUncaughtExceptionHandler();

    private delegate void ReporterDelegate(IntPtr ex);

    private static void ConvertToNsExceptionAndAbort(object e)
    {
        var nse = new NSException(".NET Exception", e.ToString(), null);
        var uncaught = NSGetUncaughtExceptionHandler();
        var dele = (ReporterDelegate)Marshal.GetDelegateForFunctionPointer(uncaught, typeof(ReporterDelegate));
        dele(nse.Handle);
    }

The end result will be a crash trace that includes a section like this written into the standard PLCrashReporter format

        Exception Type:  SIGABRT
        Exception Codes: #0 at 0x90c03a6a
        Crashed Thread:  0

        Application Specific Information:
        *** Terminating app due to uncaught exception '.NET Exception', reason: 'System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: Test Exception
          at Core.Screens.SettingsHtmlProvider.CrashTest () [0x00022] in /Users/tj/Developer/makax/Core/CoreShared/Screens/SettingsHtmlProvider.cs:192 
          at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
          at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00044] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:230 
          --- End of inner exception stack trace ---
          at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0005c] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:238 
          at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MethodBase.cs:114 
          at Core.Html.IHTMLGeneratorExtensions.ReflectiveRoute (IHtmlGenerator generator, Core.Html.DdxMessage message) [0x0009c] in /Users/tj/Developer/makax/Core/CoreShared/HTMLProvider.cs:575 
          at Core.Html.SimpleHtmlProvider.FromUi (Core.Html.DdxMessage message) [0x00003] in /Users/tj/Developer/makax/Core/CoreShared/HTMLProvider.cs:747 
          at Core.Html.BenchWebView.PullEventsFromUi () [0x00094] in /Users/tj/Developer/makax/Core/CoreIOS/iOS_HTMLProvider.cs:124 
          at Core.Html.BenchWebView.RouteUrl (System.String url) [0x00029] in /Users/tj/Developer/makax/Core/CoreShared/HTMLProvider.cs:180 
          at Core.Html.BenchWebView.RouteDdx (MonoTouch.UIKit.UIWebView webView, MonoTouch.Foundation.NSUrlRequest request, UIWebViewNavigationType navigationType) [0x0000d] in /Users/tj/Developer/makax/Core/CoreIOS/iOS_HTMLProvider.cs:57 
          at MonoTouch.UIKit.UIWebView+_UIWebViewDelegate.ShouldStartLoad (MonoTouch.UIKit.UIWebView webView, MonoTouch.Foundation.NSUrlRequest request, UIWebViewNavigationType navigationType) [0x0000d] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIWebView.g.cs:601 
          at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
          at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 
          at App.IOS.Application.Main (System.String[] args) [0x00008] in /Users/tj/Developer/makax/App.iOS/Main.cs:16 '

        Thread 0 Crashed:
        0   libsystem_kernel.dylib              0x90c03a6a ___pthread_kill + 10
        1   libsystem_c.dylib                   0x94cbc4ec _abort + 168

This is much more meaningful than what I get otherwise, which is like this

        Exception Type:  SIGABRT
        Exception Codes: #0 at 0x38a4a1fc
        Crashed Thread:  0

        Thread 0 Crashed:
        0   libsystem_kernel.dylib              0x38a4a1fc ___pthread_kill + 8
        1   libsystem_c.dylib                   0x389fb02d _abort + 77
        2   AppIOS                              0x00b0da6c monotouch_throw_monotouch_exception (monotouch-glue.m:1369)
        3   AppIOS                              0x00a9e90f mono_invoke_unhandled_exception_hook (mini-exceptions.c:2745)
        4   AppIOS                              0x00ab0eaf mono_thread_abort_dummy (mini.c:2809)
        5   AppIOS                              0x00aa1239 mono_handle_exception_internal + 2149
        6   AppIOS                              0x00aa1307 mono_handle_exception (mini-exceptions.c:1972)
        7   AppIOS                              0x00a813e1 mono_arm_throw_exception (exceptions-arm.c:162)
        8   AppIOS                              0x003f23a8 throw_exception + 68
        9   AppIOS                              0x0026dbb8 System_Reflection_MethodBase_Invoke_object_object__ + 80
        10  AppIOS                              0x0060a334 Core_Html_IHTMLGeneratorExtensions_ReflectiveRoute_Core_Html_IHtmlGenerator_Core_Html_DdxMessage (<unknown>:1)
        11  AppIOS                              0x0060ce7c Core_Html_SimpleHtmlProvider_FromUi_Core_Html_DdxMessage (<unknown>:1)
        12  AppIOS                              0x00609874 Core_Html_BenchWebView_PullEventsFromUi (<unknown>:1)
        13  AppIOS                              0x00609920 Core_Html_BenchWebView_RouteUrl_string (<unknown>:1)
        14  AppIOS                              0x0060922c Core_Html_BenchWebView_RouteDdx_MonoTouch_UIKit_UIWebView_MonoTouch_Foundation_NSUrlRequest_MonoTouch_UIKit_UIWebViewNavigationType (<unknown>:1)
        15  AppIOS                              0x001c813c MonoTouch_UIKit_UIWebView__UIWebViewDelegate_ShouldStartLoad_MonoTouch_UIKit_UIWebView_MonoTouch_Foundation_NSUrlRequest_MonoTouch_UIKit_UIWebViewNavigationType (UIWebView.g.cs:601)
        16  AppIOS                              0x003b7168 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 200
        17  AppIOS                              0x00ab0a7f mono_jit_runtime_invoke (mini.c:6457)
        18  AppIOS                              0x00ab5ce3 mono_runtime_invoke (object.c:2827)
        19  AppIOS                              0x00a2a15f native_to_managed_trampoline_MonoTouch_UIKit_UIWebView__UIWebViewDelegate_ShouldStartLoad (registrar.m:879)
        20  UIKit                               0x30b5f999 <redacted> + 281
        21  CoreFoundation                      0x2e459424 <redacted> + 68
        22  CoreFoundation                      0x2e3a3797 <redacted> + 287

Posts

  • OSVDevelopmentOSVDevelopment GBMember

    Hi TJ, thanks for sharing this code snippet - it looks really useful. Now I am using HockeyApp, but I am not sure how to add your snippet to it. I can't seem to find a reference to "ExceptionSupport" from the following line:

    ExceptionSupport.UncaughtTaskExceptionHandler = ConvertToNsExceptionAndAbort;
    

    Any help would be much appreciated. Thanks again.

    Rana

  • JonathanDickJonathanDick CAXamarin Team, Developer Group Leader Xamurai

    @T.J.Purtell.1752 thanks for this snippet. I've actually added this to the HockeyApp component which should be updated in the next couple days :)

  • T.J.Purtell.1752T.J.Purtell.1752 USMember ✭✭

    @OSVDevelopment the exception support class is just a few utility functions. You can see them in this README for the android hockeyapp binding I made. The concepts of handling task exceptions are explained there.

    https://github.com/tpurtell/AndroidHockeyApp/blob/master/README

  • T.J.Purtell.1752T.J.Purtell.1752 USMember ✭✭
    edited April 2014

    @Redth You are welcome... But I have a newer version of the snippet which I have found works somewhat better.

    https://github.com/tpurtell/IosHockeyApp/blob/master/README#L69

    It does format protection on the error message. I also switched from the Uncaught reporter function to raising an NSException because I was having trouble getting stack traces in some cases, since the delegate couldnt be resolved...

    Perhaps adding
    public delegate void UnhandledDelegate(...); [MonoPInvokeCallback(typeof(UnhandledDelegate))]
    to
    [DllImport(MonoTouch.Constants.FoundationLibrary, EntryPoint = "NSGetUncaughtExceptionHandler")] private static extern IntPtr NSGetUncaughtExceptionHandler();
    Would let you reliably use the unhandled exception reporter and thus give slightly nicer native decoded traces than the ones produced by using the [NSException raise] call

  • T.J.Purtell.1752T.J.Purtell.1752 USMember ✭✭

    @Redth had to edit the post because the forum software really gunked it up.. code is external now

  • JonathanDickJonathanDick CAXamarin Team, Developer Group Leader Xamurai

    Thanks, I've switched to the NSException raise code you use...

    Appreciate it, learned a fair bit about native exception handling on iOS and Android lately ;)

Sign In or Register to comment.