Skip to content

Conversation

@jonathanpeppers
Copy link
Member

@jonathanpeppers jonathanpeppers commented Jun 15, 2022

Fixes: #7085
Fixes: #7102
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") VS 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.

Fixes: dotnet#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")` VS 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 dotnet#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.
@jonpryor jonpryor merged commit 3d5231c into dotnet:main Jun 16, 2022
@jonathanpeppers jonathanpeppers deleted the JNINativeWrapperNRE branch June 16, 2022 19:55
jonathanpeppers added a commit that referenced this pull request Jun 17, 2022
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.
@F-Goncalves
Copy link

Any ETA on when this fix will be released?
Or any known workaround to see the underlying exception message?

@MagicAndre1981
Copy link

It is part of 17-3 branch:

image

So, next Visual Studio for Mac 17.3 preview update should include it

@abhaylakkad
Copy link

abhaylakkad commented Aug 2, 2022

I'm getting the same error on VS for Windows v17.2.5
when navigating between pages... it gives me this error.... if i change the navigation sequence this doesn't show up... this has started recently after started using Xamarin Forms 5

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_PP_V (_JniMarshal_PP_V callback, System.IntPtr jnienv, System.IntPtr klazz) [0x0001c] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:23
at (wrapper native-to-managed) Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(intptr,intptr)

@jonathanpeppers
Copy link
Member Author

@abhayl21 if you just hit the play button, does the real error show in the console output?

It kind of seems like VS Mac isn't breaking on the right line, but this is somehow working fine in VS Windows?

@mahadevans87
Copy link

Getting the same error on VS for Windows v17.2.6. I am trying to throw a new Exception("Test"); However, the exception is caught in the unhandled exception function as -

at Android.Runtime.JNINativeWrapper._unhandled_exception (System.Exception e) [0x0000e] in ...

@MagicAndre1981
Copy link

as already said, the fix is part of 17.3 and not 17.2.x

@AdamDiament
Copy link

AdamDiament commented Aug 9, 2022

@abhayl21 if you just hit the play button, does the real error show in the console output?

It kind of seems like VS Mac isn't breaking on the right line, but this is somehow working fine in VS Windows?

@jonathanpeppers speaking for windows, no, I press play and get nothing extra in the output, the app just crashes. I'm on the 17.2.x version. For what it's worth, I upgraded to 17.3.0 preview 6, and the problem revealed itself. In my case, it was one of these:

Xamarin.CommunityToolkit.Exceptions.InvalidCommandParameterException: 'Invalid type for parameter. Expected Type  X but received Y

I'm assuming the actual exception type will be different for everyone - but maybe not, just in case.

@MagicAndre1981
Copy link

@github-actions github-actions bot locked and limited conversation to collaborators Jan 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

8 participants