Commit 3d5231c
authored
[Mono.Android] Prevent NRE in VS Mac when breaking on exceptions (#7103)
Fixes: #7085
Fixes: https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1554705
In a new Xamarin.Android project, if you go to your `OnCreate()`
method and add a `throw new Exception("test")`, Visual Studio for Mac
breaks on a `NullReferenceException` such as:
[mono-rt] [ERROR] FATAL UNHANDLED EXCEPTION: System.NullReferenceException: Object reference not set to an instance of an object.
at Android.Runtime.JNINativeWrapper._unhandled_exception (System.Exception e) [0x0000e] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:12
at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPL_V (_JniMarshal_PPL_V callback, System.IntPtr jnienv, System.IntPtr klazz, System.IntPtr p0) [0x0001d] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:111
at (wrapper native-to-managed) Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPL_V(intptr,intptr,intptr)
This does not happen in VS Windows, only VS Mac.
After reviewing my changes in 32cff43, the System.Reflection.Emit
code path does a null check for `mono_unhandled_exception_method`:
bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions;
if (filter && JNIEnv.mono_unhandled_exception_method != null) {
ig.BeginExceptFilterBlock ();
ig.Emit (OpCodes.Call, JNIEnv.mono_unhandled_exception_method);
ig.Emit (OpCodes.Ldc_I4_1);
ig.BeginCatchBlock (null!);
} else {
ig.BeginCatchBlock (typeof (Exception));
}
While the new "fast" code path, does not:
static bool _unhandled_exception (Exception e)
{
if (Debugger.IsAttached || !JNIEnv.PropagateExceptions) {
JNIEnv.mono_unhandled_exception (e);
return false;
}
return true;
}
Adding `JNIEnv.mono_unhandled_exception?.Invoke(e)` appears to solve
the problem when I build a local copy of `Mono.Android.dll` and test
it inside VS Mac. I see my exception break properly on the line I
threw the exception.
`mono_unhandled_exception` being null appears to be something
introduced in 2aff4e7. That commit's goal was to not lookup
`mono_unhandled_exception_method` at startup, but wait until an
exception is thrown. Unfortunately, `mono_unhandled_exception_method`
is null at the time that the code S.R.Emitted, so we've had this
behavior for a while!
Since we are looking at reworking this entire system with "marshal
methods" as in #7004, I think we should simply add the null check for
now. We should probably investigate the sequence of events during
startup & unhandled exceptions when the new system is in place.1 parent 0181212 commit 3d5231c
File tree
2 files changed
+2
-2
lines changed- src/Mono.Android/Android.Runtime
2 files changed
+2
-2
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
245 | 245 | | |
246 | 246 | | |
247 | 247 | | |
248 | | - | |
| 248 | + | |
249 | 249 | | |
250 | 250 | | |
251 | 251 | | |
| |||
0 commit comments