Skip to content

Conversation

@jonathanpeppers
Copy link
Member

@jonathanpeppers jonathanpeppers commented Jun 24, 2020

If you tried to debug an app with:

dotnet build HelloAndroid/HelloAndroid.csproj -t:Install,_Run -p:AndroidAttachDebugger=true

The presence of $(AndroidAttachDebugger) causes a crash on startup:

06-24 11:57:42.538 14948 14948 E mono    : Unhandled Exception:
06-24 11:57:42.538 14948 14948 E mono    : System.ArgumentNullException: Value cannot be null. (Parameter 'meth')
06-24 11:57:42.538 14948 14948 E mono    :    at System.Reflection.Emit.ILGenerator.Emit(OpCode opcode, MethodInfo meth)
06-24 11:57:42.538 14948 14948 E mono    :    at Android.Runtime.JNINativeWrapper.CreateDelegate(Delegate dlg)
06-24 11:57:42.538 14948 14948 E mono    :    at Android.App.Activity.GetOnCreate_Landroid_os_Bundle_Handler()
06-24 11:57:42.538 14948 14948 E mono    :    at Android.Runtime.AndroidTypeManager.RegisterNativeMembers(JniType nativeClass, Type type, String methods)
06-24 11:57:42.538 14948 14948 E mono    :    at Android.Runtime.JNIEnv.RegisterJniNatives(IntPtr typeName_ptr, Int32 typeName_len, IntPtr jniClass, IntPtr methods_ptr, Int32 methods_len)
06-24 11:57:42.538 14948 14948 E mono-rt : [ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentNullException: Value cannot be null. (Parameter 'meth')
06-24 11:57:42.538 14948 14948 E mono-rt :    at System.Reflection.Emit.ILGenerator.Emit(OpCode opcode, MethodInfo meth)
06-24 11:57:42.538 14948 14948 E mono-rt :    at Android.Runtime.JNINativeWrapper.CreateDelegate(Delegate dlg)
06-24 11:57:42.538 14948 14948 E mono-rt :    at Android.App.Activity.GetOnCreate_Landroid_os_Bundle_Handler()
06-24 11:57:42.538 14948 14948 E mono-rt :    at Android.Runtime.AndroidTypeManager.RegisterNativeMembers(JniType nativeClass, Type type, String methods)
06-24 11:57:42.538 14948 14948 E mono-rt :    at Android.Runtime.JNIEnv.RegisterJniNatives(IntPtr typeName_ptr, Int32 typeName_len, IntPtr jniClass, IntPtr methods_ptr, Int32 methods_len)

We need to check if mono_unhandled_exception_method is null and
respond appropriately. In get_runtime_types(), we will use a
different null check for exception_handler_method to return early.

This surfaced another problem when using the _Run target by itself:

Xamarin.Android.Common.Debugging.targets(518,2): error MSB3073: The command ""adb"  forward tcp:10000 tcp:10000" exited with code 9009.

The $(_AndroidPlatformToolsDirectory) was blank when running _Run
by itself, but things work fine if you run Install,_Run at the same
time.

This broke in fb637e0. I accidentally replaced the
AndroidPrepareForBuild MSBuild target with the version in
Xamarin.Android.Bindings.Core.targets:

https://github.com/xamarin/xamarin-android/blob/f99a3fad1b12d9674de2f624e243f296cfc40fc6/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets#L47

To fix this, I can just move the binding project version of
AndroidPrepareForBuild target to Xamarin.Android.Bindings.targets.

I added a new test verifying that breakpoints work, when running under
.NET 5.

@jonathanpeppers
Copy link
Member Author

One failure seems unrelated:

                     C:\Users\dlab14\android-toolchain\jdk-11\bin\java.exe -jar C:\Users\dlab14\android-toolchain\sdk\build-tools\29.0.2\lib\apksigner.jar sign --ks "C:\Users\dlab14\AppData\Local\Xamarin\Mono for Android\debug.keystore" --ks-pass pass:android --ks-key-alias androiddebugkey --key-pass pass:android --min-sdk-version 16 --max-sdk-version 30  C:\A\vs2019xam00000V-1\_work\2\s\bin\TestRelease\temp\DesugarFalsed8proguard\bin\Debug\UnnamedProject.UnnamedProject-Signed.apk  (TaskId:294)
                     Exception in thread "main" java.nio.file.FileAlreadyExistsException: C:\Users\dlab14\AppData\Local\Temp\apksigner25311270318992346.apk -> C:\A\vs2019xam00000V-1\_work\2\s\bin\TestRelease\temp\DesugarFalsed8proguard\bin\Debug\UnnamedProject.UnnamedProject-Signed.apk (TaskId:294)
                     at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:87) (TaskId:294)
                     at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103) (TaskId:294)
                     at java.base/sun.nio.fs.WindowsFileCopy.move(WindowsFileCopy.java:395) (TaskId:294)
                     at java.base/sun.nio.fs.WindowsFileSystemProvider.move(WindowsFileSystemProvider.java:288) (TaskId:294)
                     at java.base/java.nio.file.Files.move(Files.java:1421) (TaskId:294)
                     at com.android.apksigner.ApkSignerTool.sign(ApkSignerTool.java:352) (TaskId:294)
                     at com.android.apksigner.ApkSignerTool.main(ApkSignerTool.java:83) (TaskId:294)

Really weird, I guess this temp file apksigner uses can collide? apksigner25311270318992346.apk

@jonathanpeppers jonathanpeppers marked this pull request as ready for review June 25, 2020 04:01
If you tried to debug an app with:

    dotnet build HelloAndroid/HelloAndroid.csproj -t:Install,_Run -p:AndroidAttachDebugger=true

The presence of `$(AndroidAttachDebugger)` causes a crash on startup:

    06-24 11:57:42.538 14948 14948 E mono    : Unhandled Exception:
    06-24 11:57:42.538 14948 14948 E mono    : System.ArgumentNullException: Value cannot be null. (Parameter 'meth')
    06-24 11:57:42.538 14948 14948 E mono    :    at System.Reflection.Emit.ILGenerator.Emit(OpCode opcode, MethodInfo meth)
    06-24 11:57:42.538 14948 14948 E mono    :    at Android.Runtime.JNINativeWrapper.CreateDelegate(Delegate dlg)
    06-24 11:57:42.538 14948 14948 E mono    :    at Android.App.Activity.GetOnCreate_Landroid_os_Bundle_Handler()
    06-24 11:57:42.538 14948 14948 E mono    :    at Android.Runtime.AndroidTypeManager.RegisterNativeMembers(JniType nativeClass, Type type, String methods)
    06-24 11:57:42.538 14948 14948 E mono    :    at Android.Runtime.JNIEnv.RegisterJniNatives(IntPtr typeName_ptr, Int32 typeName_len, IntPtr jniClass, IntPtr methods_ptr, Int32 methods_len)
    06-24 11:57:42.538 14948 14948 E mono-rt : [ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentNullException: Value cannot be null. (Parameter 'meth')
    06-24 11:57:42.538 14948 14948 E mono-rt :    at System.Reflection.Emit.ILGenerator.Emit(OpCode opcode, MethodInfo meth)
    06-24 11:57:42.538 14948 14948 E mono-rt :    at Android.Runtime.JNINativeWrapper.CreateDelegate(Delegate dlg)
    06-24 11:57:42.538 14948 14948 E mono-rt :    at Android.App.Activity.GetOnCreate_Landroid_os_Bundle_Handler()
    06-24 11:57:42.538 14948 14948 E mono-rt :    at Android.Runtime.AndroidTypeManager.RegisterNativeMembers(JniType nativeClass, Type type, String methods)
    06-24 11:57:42.538 14948 14948 E mono-rt :    at Android.Runtime.JNIEnv.RegisterJniNatives(IntPtr typeName_ptr, Int32 typeName_len, IntPtr jniClass, IntPtr methods_ptr, Int32 methods_len)

We need to check if `mono_unhandled_exception_method` is `null` and
respond appropriately. In `get_runtime_types()`, we will use a
different null check for `exception_handler_method` to return early.

This surfaced another problem when using the `_Run` target by itself:

    Xamarin.Android.Common.Debugging.targets(518,2): error MSB3073: The command ""adb"  forward tcp:10000 tcp:10000" exited with code 9009.

The `$(_AndroidPlatformToolsDirectory)` was blank when running `_Run`
by itself, but things work fine if you run `Install,_Run` at the same
time.

This broke in fb637e0. I accidentally replaced the
`AndroidPrepareForBuild` MSBuild target with the version in
`Xamarin.Android.Bindings.Core.targets`:

https://github.com/xamarin/xamarin-android/blob/f99a3fad1b12d9674de2f624e243f296cfc40fc6/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets#L47

To fix this, I can just move the binding project version of
`AndroidPrepareForBuild` target to `Xamarin.Android.Bindings.targets`.

I added a new test verifying that breakpoints work, when running under
.NET 5.
@jonpryor
Copy link
Contributor

Updated commit message?

If you tried to debug an app with:

	dotnet build HelloAndroid/HelloAndroid.csproj -t:Install,_Run -p:AndroidAttachDebugger=true

The presence of `$(AndroidAttachDebugger)` causes a crash on startup:

	E mono    : Unhandled Exception:
	E mono    : System.ArgumentNullException: Value cannot be null. (Parameter 'meth')
	E mono    :    at System.Reflection.Emit.ILGenerator.Emit(OpCode opcode, MethodInfo meth)
	E mono    :    at Android.Runtime.JNINativeWrapper.CreateDelegate(Delegate dlg)
	E mono    :    at Android.App.Activity.GetOnCreate_Landroid_os_Bundle_Handler()
	E mono    :    at Android.Runtime.AndroidTypeManager.RegisterNativeMembers(JniType nativeClass, Type type, String methods)
	E mono    :    at Android.Runtime.JNIEnv.RegisterJniNatives(IntPtr typeName_ptr, Int32 typeName_len, IntPtr jniClass, IntPtr methods_ptr, Int32 methods_len)
	E mono-rt : [ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentNullException: Value cannot be null. (Parameter 'meth')
	E mono-rt :    at System.Reflection.Emit.ILGenerator.Emit(OpCode opcode, MethodInfo meth)
	E mono-rt :    at Android.Runtime.JNINativeWrapper.CreateDelegate(Delegate dlg)
	E mono-rt :    at Android.App.Activity.GetOnCreate_Landroid_os_Bundle_Handler()
	E mono-rt :    at Android.Runtime.AndroidTypeManager.RegisterNativeMembers(JniType nativeClass, Type type, String methods)
	E mono-rt :    at Android.Runtime.JNIEnv.RegisterJniNatives(IntPtr typeName_ptr, Int32 typeName_len, IntPtr jniClass, IntPtr methods_ptr, Int32 methods_len)

The cause of the crash is because we pass
`JNINativeWrapper.mono_unhandled_exception_method` to
[`ILGenerator.Emit(OpCode, MethodInfo)`][0], and
`mono_unhandled_exception_method` is `null`.

`mono_unhandled_exception_method` is a `MethodInfo` to
[`Debugger.Mono_UnhandledException()`][1], which does not exist in
.NET 5 Mono, which is why it's `null` within .NET 5.

To fix `dotnet build -t:_Run` support, cleanup
`JNINativeWrapper.get_runtime_types()` to instead check for
`JNINativeWrapper.exception_handler_method`, as
`exception_handler_method` is consistently initialized properly on
both "legacy" and .NET 5 environments.

Furthermore, update `get_runtime_types()` so that
`mono_unhandled_exception_method` is not passed to `ILGenerator.Emit()`
when it is `null`.  This avoids the `ArgumentNullException`.

This surfaced another problem when using the `_Run` target by itself:

	Xamarin.Android.Common.Debugging.targets(518,2): error MSB3073: The command ""adb"  forward tcp:10000 tcp:10000" exited with code 9009.

The `$(_AndroidPlatformToolsDirectory)` property was blank when running
the `_Run` target by itself, but things work fine if you run
`Install,_Run` at the same time.

This behavior broke in commit fb637e08.  I accidentally replaced the
`AndroidPrepareForBuild` MSBuild target with [the version][2] in
`Xamarin.Android.Bindings.Core.targets`.

To fix this, I can just move the binding project version of
`AndroidPrepareForBuild` target to `Xamarin.Android.Bindings.targets`.

I added a new test verifying that breakpoints work, when running
under .NET 5.

[0]: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.ilgenerator.emit?view=netcore-3.1#System_Reflection_Emit_ILGenerator_Emit_System_Reflection_Emit_OpCode_System_Reflection_MethodInfo_
[1]: https://github.com/mono/mono/blob/2ff424be2933f711207a8139c5792ab5d1b495a9/mcs/class/corlib/System.Diagnostics/Debugger.cs#L119-L127
[2]: https://github.com/xamarin/xamarin-android/blob/f99a3fad1b12d9674de2f624e243f296cfc40fc6/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets#L47

@jonpryor jonpryor merged commit 4cae5f5 into dotnet:master Jun 26, 2020
@jonathanpeppers jonathanpeppers deleted the dotnet-debugging branch June 26, 2020 19:18
@github-actions github-actions bot locked and limited conversation to collaborators Jan 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants