Forum Xamarin.Forms

Xamarin Forms iOS Exception Handler, get current exception handler

Gmoney494Gmoney494 USMember ✭✭
edited March 30 in Xamarin.Forms

So recently we wanted to add New Relic analytic/crash reporter to our app. Our app currently has many analytic and crash reporters all working together. However when integrating New Relic on iOS side, we get an error saying it got replaced as the exception handler: Error: The New Relic exception handler has been replaced. This may result in crashes no longer reporting to New Relic.

Now i know of the iOS limitation of one handler only (Apple Docs).

Ive tried removing the other services/libraries and i still get the error and crashes are not reported. Im wondering if its something Xamarin (or App Center SDK, Distribute, Crashes, Analytics) related more as most of these libraries are also used in conjunction with new relic on other apps i hear. So im trying to use NSGetUncaughtExceptionHandler at various points to see when/where/who replaces the New Relic one and work from there. I dont see anything in the Xamarin iOS docs about that method or where/how to use it.

Ive seen this post, Xamarin Forum Post but dont know how to use it or makes much sense to me.

Any help with the ios unhandled exeception handler would be greatly appreciated.

Best Answer

  • Gmoney494Gmoney494 USMember ✭✭
    Accepted Answer

    Finally got around to using the NSGetUncaughtExceptionHandler

    private void CheckIOSSystemExceptionHandler()
    {
    try
    {
    Debug.WriteLine($"Starting ios exception handler checks");
    var handler = NSGetUncaughtExceptionHandler();
    Dl_info info;
    dladdr(handler, out info);
    var fname = Marshal.PtrToStringAuto(info.dli_fname);
    var sname = Marshal.PtrToStringAuto(info.dli_sname);
    Debug.WriteLine($"ios exception handler checks result: {handler}\n\tFNAME: {fname}\n\tSNAME: {sname}");
    }
    catch(Exception e)
    {
    // do something with excetpion
    }
    }

    [DllImport(ObjCRuntime.Constants.FoundationLibrary, EntryPoint = "NSGetUncaughtExceptionHandler")]
    private static extern IntPtr NSGetUncaughtExceptionHandler();
    
    [DllImport(ObjCRuntime.Constants.libcLibrary)]
    internal static extern int dladdr(IntPtr addr, out Dl_info info);
    
    internal struct Dl_info
    {
      internal IntPtr dli_fname; /* Pathname of shared object */
      internal IntPtr dli_fbase; /* Base address of shared object */
      internal IntPtr dli_sname; /* Name of nearest symbol */
      internal IntPtr dli_saddr; /* Address of nearest symbol */
    }
    

Answers

  • ColeXColeX Member, Xamarin Team Xamurai

    Try to integrate relic in a blank project to see if problem persists .

    BTW , why don't you use App Center SDK ? It's the recommended way by Xamarin official .

  • Gmoney494Gmoney494 USMember ✭✭

    @ColeX I tried that and it works no problem. Dont get the error message, only thing i didnt test was a forced crash as its extra work, probably try that next to ensure things. I noted that i already use the App Center SDK, the other business units already use New Relic, which adds network calls and other errors, not just crashes, so its more of a complete diagnostic tool than App Centers Crashes. So adding New Relic is for extra data on our end and to ensure continuity with other business units.

  • ColeXColeX Member, Xamarin Team Xamurai

    Try to remove other crash Analytics sdk (app center sdk etc.)to see if problem persists.

  • Gmoney494Gmoney494 USMember ✭✭
    edited April 6

    @ColeX Ive tried that and still no luck. Whats weird we have other teams using the same combination of analytics and no luck. We have found that the Facebook SDK and App Center Crashes SDKs were causing interference and we have adjusted the implementation to not cause problems. But i still get the error message and not all crashes to get reported correctly. So thats why i need access that NSGetUncaughtExceptionHandler iOS method. To help me debug what is replacing the New Relic exception handler and work from there to ensure it doesnt happen.

  • Gmoney494Gmoney494 USMember ✭✭
    Accepted Answer

    Finally got around to using the NSGetUncaughtExceptionHandler

    private void CheckIOSSystemExceptionHandler()
    {
    try
    {
    Debug.WriteLine($"Starting ios exception handler checks");
    var handler = NSGetUncaughtExceptionHandler();
    Dl_info info;
    dladdr(handler, out info);
    var fname = Marshal.PtrToStringAuto(info.dli_fname);
    var sname = Marshal.PtrToStringAuto(info.dli_sname);
    Debug.WriteLine($"ios exception handler checks result: {handler}\n\tFNAME: {fname}\n\tSNAME: {sname}");
    }
    catch(Exception e)
    {
    // do something with excetpion
    }
    }

    [DllImport(ObjCRuntime.Constants.FoundationLibrary, EntryPoint = "NSGetUncaughtExceptionHandler")]
    private static extern IntPtr NSGetUncaughtExceptionHandler();
    
    [DllImport(ObjCRuntime.Constants.libcLibrary)]
    internal static extern int dladdr(IntPtr addr, out Dl_info info);
    
    internal struct Dl_info
    {
      internal IntPtr dli_fname; /* Pathname of shared object */
      internal IntPtr dli_fbase; /* Base address of shared object */
      internal IntPtr dli_sname; /* Name of nearest symbol */
      internal IntPtr dli_saddr; /* Address of nearest symbol */
    }
    
Sign In or Register to comment.