Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a global uncaught exception handler similar to WPF and other toolkits #12040

Closed
Therzok opened this issue Jun 29, 2021 · 3 comments
Closed
Labels
enhancement The issue or pull request is an enhancement
Milestone

Comments

@Therzok
Copy link
Contributor

Therzok commented Jun 29, 2021

Steps to Reproduce

  1. Have any exception bubble through to the UI loop
  2. Observe the app crashes with SIGABRT
  3. By adding a try/catch around NSApplicationMain you catch the exception but the application's main loop still stops.

This can be seen with native shell implementations of VSMac.

Expected Behavior

Xamarin.Mac should provide some event to listen on for uncaught exceptions. That would allow applications to avoid crashes most of the time, by having the main loop driven by the toolkit handling them.

See the equivalent WPF API here: https://docs.microsoft.com/en-us/dotnet/api/system.windows.application.dispatcherunhandledexception?redirectedfrom=MSDN&view=net-5.0

Actual Behavior

The exception bubbles through to NSApplicationMain caller, because there is no manual RunLoop handling happening on Xamarin.Mac's side. That means, we let AppKit handle running the loop iterations, so we have no ability to get monitor for exceptions.

@rolfbjarne
Copy link
Member

That means, we let AppKit handle running the loop iterations

I don't think it's a good idea to try to replicate AppKit's runloop logic in managed code, so that we can catch (and ignore) any managed exceptions that may happen. That sounds quite complicated and easy to get wrong, if it's even possible in the first place.

If you really want to try this to see if it's possible, you can replace the call you have to the NSApplicationMain method in your managed Main:

AppKit.NSApplication.NSApplicationMain(Int32,String[])
AppKit.NSApplication.Main(String[])

with your own runloop implementation.

The correct fix (although I understand it's not a particularly nice fix), is to handle any managed exceptions before they reach the runloop logic in the first place.

So for instance for this stack trace:

[VisualStudio] xamarin_process_managed_exception +908
[VisualStudio] _ZL30native_to_managed_trampoline_6P11objc_objectP13objc_selectorPP11_MonoMethodS0_j +507
[VisualStudio] -[VisualStudioMac_UI_Shell_CocoaShellDocumentViewContent viewSelectorChanged:] +53

You'd have to add exception handling in the managed CocoaShellDocumentViewContent.ViewSelectorChanged method, and then you can decide there how to handle that exception.

@rolfbjarne rolfbjarne added the enhancement The issue or pull request is an enhancement label Jun 29, 2021
@rolfbjarne rolfbjarne added this to the Future milestone Jun 29, 2021
@Therzok
Copy link
Contributor Author

Therzok commented Jun 29, 2021

The main issue here is that we don't control all the code of the application. Being an extensible application, anything can implement an NSView/NSWindow that will end up throwing.

Unless every override of every method is marked with a try/catch to intercept (which can easily result in huge code size increase), I don't see how that could be done.

The framework needs to provide support for this.

@rolfbjarne
Copy link
Member

I think this will possible once dotnet/runtime#101560 is implemented, so closing as a duplicate of that issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement The issue or pull request is an enhancement
Projects
None yet
Development

No branches or pull requests

2 participants