-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Raise the AppDomain.UnhandledException event from Objective-C bridge #102730
Comments
Tagging subscribers to this area: @dotnet/interop-contrib |
@rolfbjarne Would #101560 help with this issue? If not, is this a .NET 9 ask? |
No, I don't think so, that's a proposal to support ignoring unhandled exceptions, while our exceptions can't be ignored, the process will terminate soon after no matter what the handler does. The fatal error handler would eventually be called, but getting the unhandled managed exception (to log it for instance) after the error handled has been called due to a SIGABRT wouldn't be easy, so it's not really a good alternative.
Yes, please! |
Maybe that in the Objective-C unhandled exception callback, we can unwind to the first managed frame and rethrow the managed exception from there. That way, the exception that was not handled by the Objective-C stuff would continue flowing into the managed caller of that code and possibly get even handled in the managed code or hit the standard unhandled exception path that would also raise the AppDomain.UnhandledException event. |
There isn't necessarily any managed frames up the stack (in fact probably won't be any). Also note that there may be both managed and Objective-C exception handled up the stack... because Apple does something like this sometimes: void someFunction ()
{
@try {
callUserCode ();
} @catch (NSException *ex) {
terminateDueToUnhandledObjectiveCException (ex);
}
} Stack trace: https://gist.github.com/rolfbjarne/5ab15ce73bc6476d4cee83cff387dd30 frame 0 is our unhandled Objective-C exception callback. In any case, it doesn't sound like a good idea to try to recover and continue executing from this stack trace:
We end up with a kind of chicken-and-egg problem here: exceptions are only truly unhandled if there are neither Objective-C exception handlers nor managed exception handlers up the stack.
This means that (almost) all unhandled managed exceptions will actually be converted into Objective-C exceptions at some point. We reach the end when the there are no Objective-C exception handlers on the stack, and the unhandled Objective-C exception callback is called. At this point we can inspect the Objective-C exception, and determine whether it originated from a managed exception (and this is where we want to call AppDomain.UnhandledException). |
Ok, I can see I have not considered the cases when objective-C thread is reverse-pinvoking managed code or when there is an objective-C host. What I was talking about was a case when managed code app would call objective-C method. |
…xception. (#20656) Call mono_unhandled_exception to raise AppDomain.UnhandledException when managed exceptions are unhandled. Partial fix for #15252 (for MonoVM, still pending for CoreCLR, which needs dotnet/runtime#102730 fixed first).
@VSadov Do you have any thoughts on adding an additional API to #101560? The issue here is attempting to trigger the runtime's UnhandledException infrastructure on demand. It seems like it fits nicely with the aforementioned API. The API itself is likely uninteresting, but the semantics definitely are. namespace System.Runtime.ExceptionServices
{
public static class ExceptionHandling
{
/// <summary>
/// Triggers the runtime's UnhandledException infrastructure.
/// </summary>
/// <param name="exception">Exception to trigger</exception>
/// <remarks>
/// QUESTION: What happens on return?
/// </remarks>
public static void TriggerUnhandledExceptionHandlers(Exception exception);
}
} /cc @jkotas |
@AaronRobinsonMSFT @jkotas any updates on this? Is there still time to get this in .NET 9? |
.NET 9 is done. We should address this scenario as part of #101560 in .NET 10. |
Background and motivation
The ObjectiveCMarshal.Initialize method takes a callback that's called if an exception is supposed to be thrown when returning from managed code to native code.
This works fine, but if we determine that the exception is truly unhandled, there doesn't seem to be a way for us to invoke the AppDomain.UnhandledException event before terminating the process.
This event is often used by customers when logging app crashes, so the fact that we don't always raise it becomes a problem (xamarin/xamarin-macios#15252). We have other events (our own) we raise, but if we could raise the event everybody else uses that would be preferrable.
Note that we'd need the same for Mono.Looks like we can usemono_unhandled_exception
for Mono.API Proposal
API Usage
The method would be called when we detect that there are no Objective-C exception handlers nor any managed exception handlers on the stack.
Currently this happens:
AppDomain.UnhandledException
event, before aborting. Note that we still have access to the original managed exception at this point.It would also be nice if we could tell the debugger about these unhandled exception as well, but I don't have any idea how that would look.
Alternative Designs
No response
Risks
No response
The text was updated successfully, but these errors were encountered: