-
Notifications
You must be signed in to change notification settings - Fork 5.1k
[mono][android] Bring back api used by xamarin.android #55904
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
namespace System | ||
{ | ||
public static partial class AppContext | ||
{ | ||
internal static void DoUnhandledException (object sender, UnhandledExceptionEventArgs args) | ||
{ | ||
if (UnhandledException != null) | ||
UnhandledException (sender, args); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,15 @@ | ||||
// Licensed to the .NET Foundation under one or more agreements. | ||||
// The .NET Foundation licenses this file to you under the MIT license. | ||||
|
||||
namespace System | ||||
{ | ||||
public partial class AppDomain | ||||
{ | ||||
#if TARGET_ANDROID | ||||
internal void DoUnhandledException (UnhandledExceptionEventArgs args) | ||||
{ | ||||
AppContext.DoUnhandledException (this, args); | ||||
} | ||||
#endif | ||||
Comment on lines
+8
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is this called and why is it Android specific? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't fully understand how this stuff works, but xam-android is catching all exceptions in https://github.com/xamarin/xamarin-android/blob/main/src/Mono.Android/Android.Runtime/JNINativeWrapper.cs#L52. This wrapper might call into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see that code used anywhere and I don't think it should be Android-specific. Handling of unhandled exceptions should work everywhere. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't know which code you're referring to specifically, given that @BrzVlad linked to relevant places of code. Thus, an example: suppose you have the following Xamarin.Android code: using Android.App;
using Android.OS.;
using System;
[Activity (MainLauncher = true)
partial class MyActivity : Activity {
public override void OnCreate (Bundle savedInstanceState) => throw new System.Exception ("Yolo!");
} At runtime, the Java Callable Wrapper for On entry to
(2) is effectively: static void n_OnCreate(IntPtr env, IntPtr self, IntPtr bundle)
{
try {
Activity.n_OnCreate_Landroid_os_Bundle_ (env, self, bundle);
}
catch (Exception e) {
AndroidEnvironment.UnhandledException (e);
}
} (3) would be: partial class Activity {
static void n_OnCreate_Landroid_os_Bundle_ (IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState)
{
var __this = global::Java.Lang.Object.GetObject<Android.App.Activity> (jnienv, native__this, JniHandleOwnership.DoNotTransfer)!;
var savedInstanceState = global::Java.Lang.Object.GetObject<Android.OS.Bundle> (native_savedInstanceState, JniHandleOwnership.DoNotTransfer);
__this.OnCreate (savedInstanceState);
}
}
JNIEnv.Throw(new JavaProxyThrowable(e)); When This will cause frame (1) and callers of (1) to eventually unwind, potentially unwinding the entire Java-side stack. When that happens, Java will eventually execute: java.lang.Thread.getUncaughtExceptionHandler()
.uncaughtException(currentThread, currentException); During startup, Xamarin.Android registers an uncaught exception handler with Java -- the We don't want the We thus need a way for Xamarin.Android to cause the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apparently the implicit question was "how do we actually register the Java-side unhandled exception support"? The
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As per above conversation, I think we don't actually need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @grendello will work on a change to xamarin-android wherein we call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eventually, does it make sense to do something similar to XI? Register: And this is the runtime API it's using Line 60 in e0024e2
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's try to use the existing embedding API first before considering this PR. |
||||
} | ||||
} |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Xamarin Android is calling this, it should be designed, exposed and tested as proper public API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Android has been calling this method for over 10 years: https://github.com/xamarin/monodroid/commit/3e9de5a51b
Other related reading:
Yes, it should be designed, exposed, and tested. That said, this is what we had, and what worked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have
mono_unhandled_exception
which is part of the embedding API and should do the same thing. Android could also switch to using it instead.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BrzVlad : which raises a different question:
mono_unhandled_exception()
(added in 2002 via mono/mono@ce9497a) predates xamarin/monodroid@3e9de5a (2010), so why wasn't that used in the first place?A difference between the two is debugger interaction:
Debugger::Mono_UnhandledException
, in legacy, hitsdebugger_agent_unhandled_exception()
:Meanwhile, in
mono_unhandled_exception()
: https://github.com/mono/mono/blob/78c2b8da29881eccda4c27ca7b2b7e9ed451c55f/mono/metadata/object.c#L5105-L5211I don't see any calls to
mini_get_dbg_callbacks()
, much lessmini_get_dbg_callbacks()->unhandled_exception
.Calling
mono_unhandled_exception()
would allow re-working theAppDomain.DoUnhandledException()
codepath (below), but is otherwise unrelated toDebugger.Mono_UnhandledException
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, so I would expect as part of this PR:
Code comments that explain that this is a legacy private reflection hack, with links where Xamarin Android calls it, so that the next person looking at this code won't delete it as dead code again.
API proposal issue should be opened to create proper public managed API for this that Xamarin Android can switch to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonpryor Yeah, I was actually referring to the
DoUnhandledException
callback. I think it makes sense formono_unhandled_exception
to also call into the debugger. @thaystg seems to have looked into removing theDebugger.Mono_UnhandledException
API altogether, maybe she has some ideas.Anyhow. This is a regression on android on the new netcore profile and I'm not sure it is worthwhile to bother refactoring it so late in the release cycle. We could keep the legacy code for this release, and remove these API's for next release.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is the best approach to fix this regression, as I was working on implementing other things I couldn't look before preview 7.
I was planning to look at this, during this week, but maybe you are right it's too late for this release, we could only remove it on next release.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonpryor , you don't see
mini_get_dbg_callbacks()->unhandled_exception
because with componentize work this was renamed to:mono_component_debugger ()->unhandled_exception
, and it's still in the code:runtime/src/mono/mono/mini/mini-runtime.c
Line 4611 in c8f9a24
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thaystg : the
Debugger::Mono_UnhandledException_internal
internal call is registered, but it doesn't exist: https://github.com/dotnet/runtime/blob/c8f9a24ca0ebf6d9593e00ccbc7353510a0e0213/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.csHence the change below, which re-introduces the declaration for the
Debugger::Mono_UnhandledException
internal call toDebugger.cs
.