Description
Background and motivation
Extension of prior exception handling utilities from #101560.
In scenarios where .NET is not the process owner (for example, iOS or Android), it can occur that an exception is about to take down the process but that it didn't originate in the .NET environment. Having a way to trigger .NET's unhandled exception infrastructure for applications would allow for improved application UX.
This event is often used by customers when logging app crashes, so the fact that we don't always raise it becomes a problem (dotnet/macios#15252).
API Proposal
The API would return after running any supplied handlers. It is expected that the process would terminate shortly after this returns. Any handler set via ExceptionHandling.SetUnhandledExceptionHandler()
would not be called since this is coming from outside of the .NET environment and therefore it isn't possible for .NET to ensure the exception can be ignored from the other system.
namespace System.Runtime.ExceptionServices;
public static class ExceptionHandling
{
+ public static void ReportUnhandledException(Exception exception);
}
API Usage
[UnmanagedCallersOnly]
public static void ExternalCaller(IntPtr externalExceptionData)
{
// Marshal the externalExceptionData to a .NET Exception that represents
// an unhandled exception outside of the .NET environment.
Exception e = ...
ExceptionHandling. ReportUnhandledException(e);
}
static void MyExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
Debug.Assert(args.IsTerminating);
Exception e = (Exception)args.ExceptionObject;
Console.WriteLine("MyHandler caught : {0}", e.Message);
}
AppDomain.UnhandledException += MyExceptionHandler;
Alternative Designs
Original proposal
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 (dotnet/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 use mono_unhandled_exception
for Mono.
API Proposal
namespace System.Runtime.InteropServices.ObjectiveC;
public static class ObjectiveCMarshal
{
// This raises the AppDomain.UnhandledException event
public void OnUnhandledException (Exception exception);
}
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:
- The ObjectiveCMarshal unhandled exception propagation handler is called.
- We convert the managed exception into an Objective-C exception and throw the Objective-C exception.
- Objective-C doesn't find any Objective-C exception handlers, and calls our Objective-C unhandled exception callback
- In our Objective-C unhandled exception callback, we abort the process. This is where we'd like to raise the
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
Metadata
Metadata
Assignees
Type
Projects
Status
No status