-
Notifications
You must be signed in to change notification settings - Fork 564
Description
Android framework version
net10.0-android (Preview)
Affected platform version
.NET 10
Description
Uncaught exceptions crash the app and don't raise the AppDomain.CurrentDomain.UnhandledException event. This is an API that's relied on by crash reporting tools.
Steps to Reproduce
- Add the following snippet somewhere into a new project:
AppDomain.CurrentDomain.UnhandledException += (sender, e)
{
Console.WriteLine($"UnhandledException: {e.ExceptionObject}");
};
throw new Exception("testing");With Mono, the UnhandledException: log will be produced, with CoreCLR it won't.
My current best understanding is that we fail to propagate the managed exception across .NET/Java boundary:
android/src/Mono.Android/Android.Runtime/AndroidRuntimeInternal.cs
Lines 16 to 39 in bb5968d
| static AndroidRuntimeInternal () | |
| { | |
| if (RuntimeFeature.IsMonoRuntime) { | |
| mono_unhandled_exception = MonoUnhandledException; | |
| } else if (RuntimeFeature.IsCoreClrRuntime) { | |
| mono_unhandled_exception = CoreClrUnhandledException; | |
| } else { | |
| throw new NotSupportedException ("Internal error: unknown runtime not supported"); | |
| } | |
| } | |
| static void CoreClrUnhandledException (Exception ex) | |
| { | |
| // TODO: Is this even needed on CoreCLR? | |
| } | |
| // Needed when running under CoreCLR, which doesn't allow icalls/ecalls. Any method which contains any reference to | |
| // an unregistered icall/ecall method will fail to JIT (even if the method isn't actually called). In this instance | |
| // it affected the static constructor which tried to assign `RuntimeNativeMethods.monodroid_debugger_unhandled_exception` | |
| // to `mono_unhandled_exception` at the top of the class. | |
| static void MonoUnhandledException (Exception ex) | |
| { | |
| RuntimeNativeMethods.monodroid_debugger_unhandled_exception (ex); | |
| } |
... but it's possible the problem is somewhere else completely.
The InstallAndRunTests.SubscribeToAppDomainUnhandledException is currently disabled for CoreCLR because of this:
android/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs
Lines 216 to 251 in bb5968d
| // TODO: check if AppDomain.CurrentDomain.UnhandledException even works in CoreCLR | |
| [Test] | |
| public void SubscribeToAppDomainUnhandledException ([Values (AndroidRuntime.MonoVM, AndroidRuntime.CoreCLR)] AndroidRuntime runtime) | |
| { | |
| if (runtime == AndroidRuntime.CoreCLR) { | |
| Assert.Ignore ("AppDomain.CurrentDomain.UnhandledException doesn't work in CoreCLR"); | |
| return; | |
| } | |
| proj = new XamarinAndroidApplicationProject () { | |
| IsRelease = true, | |
| }; | |
| proj.SetRuntime (runtime); | |
| if (runtime == AndroidRuntime.MonoVM) { | |
| proj.SetAndroidSupportedAbis ("armeabi-v7a", "arm64-v8a", "x86", "x86_64"); | |
| } else { | |
| proj.SetRuntimeIdentifiers (new [] {"arm64-v8a", "x86_64"}); | |
| } | |
| proj.MainActivity = proj.DefaultMainActivity.Replace ("//${AFTER_ONCREATE}", | |
| @" AppDomain.CurrentDomain.UnhandledException += (sender, e) => { | |
| Console.WriteLine (""# Unhandled Exception: sender={0}; e.IsTerminating={1}; e.ExceptionObject={2}"", | |
| sender, e.IsTerminating, e.ExceptionObject); | |
| }; | |
| throw new Exception (""CRASH""); | |
| "); | |
| builder = CreateApkBuilder (); | |
| Assert.IsTrue (builder.Install (proj), "Install should have succeeded."); | |
| RunProjectAndAssert (proj, builder); | |
| string expectedLogcatOutput = "# Unhandled Exception: sender=System.Object; e.IsTerminating=True; e.ExceptionObject=System.Exception: CRASH"; | |
| Assert.IsTrue ( | |
| MonitorAdbLogcat (CreateLineChecker (expectedLogcatOutput), | |
| logcatFilePath: Path.Combine (Root, builder.ProjectDirectory, "startup-logcat.log"), timeout: 60), | |
| $"Output did not contain {expectedLogcatOutput}!"); | |
| } |
Did you find any workaround?
No response