Skip to content

Conversation

@simonrozsival
Copy link
Member

When using the CoreCLR runtime, the AppDomain.UnhandledException event handlers were not raised. This has many implications, one of them being that crash reporting tools don't work as expected.

This PR adds the missing functionality of forwarding the exceptions from native code to managed code. Some notable aspects of this PR:

  • We use ExceptionHandling.RaiseAppDomainUnhandledExceptionEvent instead of Mono's native mono_unhandled_exception to raise the events. There is one observable change in behavior and that's that CoreCLR does not pass the sender (Mono passes the app domain). The existing unit test had to reflect this change.
  • The JNIEnvInit.Initialize method returns the UCO fnptr through the args struct. I believe this is a clean way of doing it and hopefully it doesn't add too much confusion. This is a more efficient way of obtaining the function pointer than calling coreclr_create_delegate. We have to use this to get the delegate for the Initialize method itself, but it might be a good idea to return the funptr for RegisterNatives this way as well (and avoid passing it completely at some later point when we have working Marshal Methods on CoreCLR, allowing for (unmeasurably?) faster startup and improved trimming)

Closes #10657
Closes #10654

@simonrozsival simonrozsival added the Area: CoreCLR Issues that only occur when using CoreCLR. label Dec 29, 2025
@simonrozsival simonrozsival requested review from Copilot and grendello and removed request for grendello and jonathanpeppers December 29, 2025 12:47
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements unhandled exception propagation for the CoreCLR runtime, enabling AppDomain.UnhandledException event handlers to function correctly. Previously, these event handlers were not raised in CoreCLR, breaking crash reporting tools and other error handling mechanisms.

Key changes:

  • Adds a new function pointer mechanism to propagate uncaught exceptions from native code to managed code
  • Uses ExceptionHandling.RaiseAppDomainUnhandledExceptionEvent for CoreCLR instead of Mono's native mono_unhandled_exception
  • Returns the function pointer through the JnienvInitializeArgs struct to avoid an extra coreclr_create_delegate call, improving efficiency

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs Removes CoreCLR test skip and updates test assertions to handle different sender values (MonoVM passes System.Object, CoreCLR passes null)
src/native/common/include/managed-interface.hh Adds jnienv_propagate_uncaught_exception_fn typedef and propagateUncaughtExceptionFn field to JnienvInitializeArgs struct
src/native/clr/include/host/host.hh Declares propagate_uncaught_exception static method and jnienv_propagate_uncaught_exception static field
src/native/clr/host/host.cc Implements function pointer initialization and propagate_uncaught_exception method with null-check guard
src/native/clr/host/host-jni.cc Updates JNI bridge to forward calls to Host::propagate_uncaught_exception
src/Mono.Android/Android.Runtime/JNIEnvInit.cs Adds PropagateUncaughtException UCO method and returns its function pointer through args struct
src/Mono.Android/Android.Runtime/JNIEnv.cs Replaces TODO comment with call to ExceptionHandling.RaiseAppDomainUnhandledExceptionEvent for CoreCLR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: CoreCLR Issues that only occur when using CoreCLR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CoreCLR] Propagate unhandled Java exceptions [CoreCLR] Propagate unhandled .NET exceptions

2 participants