From 7aa5b98ba14dcfbd04b43fc5c6bf154af14a5b5c Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 1 Mar 2023 19:26:36 -0500 Subject: [PATCH] [Mono.Android] Print type & member remapping info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context: f6f11a5a797cd8602854942dccb0f2b1db57c473 Context: f99fc814b0dcc021a441e70bb5a487b2034f6760 How do we diagnose type & member remapping issues? If (when) things don't work as anticipated, what do we do? If a method is remapped *and* the remapped-to method cannot be found, then [Java.Interop will write a message to stderr][0]: warning: For declared method `java/lang/Object.remappedToToString.()Ljava/lang/String;`, could not find requested method `java/lang/Object.toString.()Ljava/lang/String;`! which is a scenario we think/assume Shouldn't Happen™. If it *does* happen, we believe that the above message will be sufficient to fix the problem. However, in the "happy" path in which the replacement method is found *or* the "less-happy" path in which *nothing happens*, how do we get insight to check or verify what's going on? Update `AndroidTypeManager.GetStaticMethodFallbackTypesCore()` and `AndroidTypeManager.GetReplacementMethodInfoCore()` so that they print out *successful* type & member remapping when the "assembly" log category is enabled: adb shell setprop debug.mono.log default,assembly When the assembly log category is enabled, invocations of `AndroidTypeManager.GetStaticMethodFallbackTypesCore()` will print messages such as the following to `adb logcat`: D monodroid-assembly : Remapping type `com/xamarin/interop/RenameClassBase1` to one of { `com/xamarin/interop/DesugarRenameClassBase1`, `com/xamarin/interop/RenameClassBase1$-CC` } When the assembly log category is enabled, invocations of `AndroidTypeManager.GetReplacementMethodInfoCore()` will print messages such as the following to `adb logcat` *when a replacement method will be attempted*: D monodroid-assembly : Remapping method `java/lang/Object.remappedToToString()Ljava/lang/String;` to `java/lang/Object.toString.()Ljava/lang/String;`; param-count: 0; instance-to-static? false This will hopefully provide enough information to reason through type and member remapping behavior. [0]: https://github.com/xamarin/java.interop/blob/77800dda83c2db4d90b501c00069abc9880caaeb/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods.cs#L123 --- .../Android.Runtime/AndroidRuntime.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Mono.Android/Android.Runtime/AndroidRuntime.cs b/src/Mono.Android/Android.Runtime/AndroidRuntime.cs index e819369fef9..b2436fb01b6 100644 --- a/src/Mono.Android/Android.Runtime/AndroidRuntime.cs +++ b/src/Mono.Android/Android.Runtime/AndroidRuntime.cs @@ -317,10 +317,16 @@ protected override IEnumerable GetSimpleReferences (Type type) var typeWithPrefix = desugarType.ToString (); var typeWithSuffix = $"{jniSimpleReference}$-CC"; - return new[]{ + var replacements = new[]{ GetReplacementTypeCore (typeWithPrefix) ?? typeWithPrefix, GetReplacementTypeCore (typeWithSuffix) ?? typeWithSuffix, }; + + if (Logger.LogAssembly) { + var message = $"Remapping type `{jniSimpleReference}` to one one of {{ `{replacements[0]}`, `{replacements[1]}` }}"; + Logger.Log (LogLevel.Debug, "monodroid-assembly", message); + } + return replacements; } protected override string? GetReplacementTypeCore (string jniSimpleReference) @@ -350,11 +356,19 @@ protected override IEnumerable GetSimpleReferences (Type type) var method = new JniRemappingReplacementMethod (); method = Marshal.PtrToStructure(retInfo); + var newSignature = jniMethodSignature; int? paramCount = null; if (method.is_static) { paramCount = JniMemberSignature.GetParameterCountFromMethodSignature (jniMethodSignature) + 1; - jniMethodSignature = $"(L{jniSourceType};" + jniMethodSignature.Substring ("(".Length); + newSignature = $"(L{jniSourceType};" + jniMethodSignature.Substring ("(".Length); + } + + if (Logger.LogAssembly) { + var message = $"Remapping method `{jniSourceType}.{jniMethodName}{jniMethodSignature}` to " + + $"`{method.target_type}.{method.target_name}{newSignature}`; " + + $"param-count: {paramCount}; instance-to-static? {method.is_static}"; + Logger.Log (LogLevel.Debug, "monodroid-assembly", message); } return new JniRuntime.ReplacementMethodInfo { @@ -363,7 +377,7 @@ protected override IEnumerable GetSimpleReferences (Type type) SourceJniMethodSignature = jniMethodSignature, TargetJniType = method.target_type, TargetJniMethodName = method.target_name, - TargetJniMethodSignature = jniMethodSignature, + TargetJniMethodSignature = newSignature, TargetJniMethodParameterCount = paramCount, TargetJniMethodInstanceToStatic = method.is_static, };