Prevent NREX when instantiating Java.Lang.StackTraceElement#8795
Prevent NREX when instantiating Java.Lang.StackTraceElement#8795
Conversation
Context: #8788 (comment) Context: https://developer.android.com/reference/java/lang/StackTraceElement?hl=en#StackTraceElement(java.lang.String,%20java.lang.String,%20java.lang.String,%20int) `Java.Lang.StackTraceElement` constructor requires the `declaringClass` and `methodName` parameters to never be `null`. Pass the string `Unknown` whenever any of this information is missing from the managed stack frame. Additionally, the `lineNumber` parameter is now set to `-2` if we think a stack frame points to native code.
|
@jonpryor our // Metadata.xml XPath constructor reference: path="/api/package[@name='java.lang']/class[@name='StackTraceElement']/constructor[@name='StackTraceElement' and count(parameter)=4 and parameter[1][@type='java.lang.String'] and parameter[2][@type='java.lang.String'] and parameter[3][@type='java.lang.String'] and parameter[4][@type='int']]"
[Register (".ctor", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V", "")]
public unsafe StackTraceElement (string? declaringClass, string? methodName, string? fileName, int lineNumber) : base (IntPtr.Zero, JniHandleOwnership.DoNotTransfer)Shouldn't |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run |
We do not manually assign nullability, we simply pass along what Google has annotated, and it appears this method has no public final class StackTraceElement implements Serializable {
public StackTraceElement(String declaringClass, String methodName, String fileName, int lineNumber) {
throw new RuntimeException("Stub!");
}
...
} |
We only flag a parameter or return type as non-null if it contains one of these annotations: https://github.com/xamarin/java.interop/blob/e557044f81917b61031f2ee887700ac43a526475/src/Xamarin.Android.Tools.Bytecode/XmlClassDeclarationBuilder.cs#L503-L512 By default, then, everything is allowed to be We can use Metadata to update these parameters so that @jpobst would such an update be a good idea? <attr
path="/api/package[@name='java.lang']/class[@name='StackTraceElement']/constructor/parameter[@type='java.lang.String']"
name="not-null">true</attr>It should be noted that (1) the above metadata is an oversimplication -- the filename String parameter should be allowed to be null -- and (2) the above Metadata results in a build break: |
There are likely thousands of Android APIs that are missing nullability information. Thus our stated policy is that we will not manually fix them: https://learn.microsoft.com/en-us/xamarin/android/release-notes/11/11.0#monoandroid-nullable-reference-types-compatibility. |
While it was fine before nullable support was added to .NET, I think now it would be good to change that policy... I realize it's a lot of work, but this is where the compiler (or the IDE) can help avoid mistakes like this one. |
| MethodBase? managedMethod = StackFrameGetMethod (managedFrame); | ||
|
|
||
| // https://developer.android.com/reference/java/lang/StackTraceElement?hl=en#StackTraceElement(java.lang.String,%20java.lang.String,%20java.lang.String,%20int) | ||
| int lineNumber; |
There was a problem hiding this comment.
I'm reminded of: https://github.com/xamarin/xamarin-android/pull/8758/files#r1504920023
wherein StackFrame.GetMethod() may return null, while StackFrame.ToString() contains useful information.
I suspect that we should instead "lean in" to using StackFrame.ToString(), as we know managedFrame is not null (if it were, we'd get a NullReferenceException from here!).
There was a problem hiding this comment.
I don't want to use ToString() output, as it's unwieldy to handle in a presentable manner. However, the information mentioned above can be obtained using the StackFrame extension methods (which this PR already uses in a small capacity). We can get this kind of output:
MainActivity.OnCreate() + 0x37 at offset 55 in file:line:column <filename unknown>:0:0
Only I'm not sure how useful it really is.
There was a problem hiding this comment.
@grendello: parsing MainActivity.OnCreate() is more useful than providing Unknown.Unknown:-1 as the stack frame information to Java. Is it perfect? No. But it's better than the alternative.
* main: [Mono.Android] Fix missing enum issues that cause BG8800 warnings. (#8707) Bump external/Java.Interop from `3436a30` to `5bca8ad` (#8803) Bump to xamarin/monodroid@77124dc1 (#8804) Bump to dotnet/installer@e911f5c82c 9.0.100-preview.3.24161.2 (#8802) Bump to xamarin/Java.Interop/main@3436a30 (#8799)
…8795) Context: #8788 (comment) Context: 1aa0ea7 The [`java.lang.StackTraceElement(String, String, String, int)`][0] constructor requires that the `declaringClass` and `methodName` parameters never be `null`. Failure to do so results in a `NullPointerException`: I DOTNET : JavaProxyThrowable: translation threw an exception: Java.Lang.NullPointerException: Declaring class is null I DOTNET : at Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod(JniObjectReference instance, JniObjectReference type, JniMethodInfo method, JniArgumentValue* args) I DOTNET : at Java.Interop.JniPeerMembers.JniInstanceMethods.FinishCreateInstance(String constructorSignature, IJavaPeerable self, JniArgumentValue* parameter s) I DOTNET : at Java.Lang.StackTraceElement..ctor(String declaringClass, String methodName, String fileName, Int32 lineNumber) I DOTNET : at Android.Runtime.JavaProxyThrowable.TranslateStackTrace() I DOTNET : at Android.Runtime.JavaProxyThrowable.Create(Exception innerException) I DOTNET : --- End of managed Java.Lang.NullPointerException stack trace --- I DOTNET : java.lang.NullPointerException: Declaring class is null I DOTNET : at java.util.Objects.requireNonNull(Objects.java:228) I DOTNET : at java.lang.StackTraceElement.<init>(StackTraceElement.java:71) I DOTNET : at crc6431345fe65afe8d98.AvaloniaMainActivity_1.n_onCreate(Native Method) Update `JavaProxyThrowable.TranslateStackTrace()` (1aa0ea7) so that if `StackFrame.GetMethod()` returns `null`, we fallback to: 1. Trying to extract class name and method name from [`StackFrame.ToString()`][1]: MainActivity.OnCreate() + 0x37 at offset 55 in file:line:column <filename unknown>:0:0 2. If (1) fails, pass `Unknown` for `declaringClass` and `methodName`. Additionally, the `lineNumber` parameter is now set to `-2` if we think a stack frame points to native code. [0]: https://developer.android.com/reference/java/lang/StackTraceElement#StackTraceElement(java.lang.String,%20java.lang.String,%20java.lang.String,%20int) [1]: https://github.com/xamarin/xamarin-android/pull/8758/files#r1504920023
* main: LEGO: Merge pull request 8818 Bump to dotnet/installer@b40c44502d 9.0.100-preview.3.24165.20 (#8817) Bump com.android.tools:r8 from 8.2.47 to 8.3.37 (#8816) [Mono.Android] Prevent NullPointerException in TranslateStackTrace (#8795) Localized file check-in by OneLocBuild Task (#8815)
* main: LEGO: Merge pull request 8818 Bump to dotnet/installer@b40c44502d 9.0.100-preview.3.24165.20 (#8817) Bump com.android.tools:r8 from 8.2.47 to 8.3.37 (#8816) [Mono.Android] Prevent NullPointerException in TranslateStackTrace (#8795) Localized file check-in by OneLocBuild Task (#8815) [Xamarin.Android.Build.Tasks] Make all assemblies RID-specific (#8478) Localized file check-in by OneLocBuild Task (#8813) [Xamarin.Android.Build.Tasks] %(AndroidAsset.AssetPack) Support (#8631)
* main: LEGO: Merge pull request 8818 Bump to dotnet/installer@b40c44502d 9.0.100-preview.3.24165.20 (#8817) Bump com.android.tools:r8 from 8.2.47 to 8.3.37 (#8816) [Mono.Android] Prevent NullPointerException in TranslateStackTrace (#8795) Localized file check-in by OneLocBuild Task (#8815) [Xamarin.Android.Build.Tasks] Make all assemblies RID-specific (#8478) Localized file check-in by OneLocBuild Task (#8813) [Xamarin.Android.Build.Tasks] %(AndroidAsset.AssetPack) Support (#8631) [runtime] Remove the last vestiges of desktop builds (#8810) [ci] Don't auto-retry APK test suites. (#8811) [Microsoft.Android.Templates] Update EN l10n template strings (#8808) Bump to xamarin/Java.Interop/main@651de42 (#8809) [Mono.Android] is now "trimming safe" (#8778) [Mono.Android] Fix missing enum issues that cause BG8800 warnings. (#8707) Bump external/Java.Interop from `3436a30` to `5bca8ad` (#8803) Bump to xamarin/monodroid@77124dc1 (#8804) Bump to dotnet/installer@e911f5c82c 9.0.100-preview.3.24161.2 (#8802) Bump to xamarin/Java.Interop/main@3436a30 (#8799) [templates] Remove redundant "template" from display name. (#8773)
* main: LEGO: Merge pull request 8818 Bump to dotnet/installer@b40c44502d 9.0.100-preview.3.24165.20 (#8817) Bump com.android.tools:r8 from 8.2.47 to 8.3.37 (#8816) [Mono.Android] Prevent NullPointerException in TranslateStackTrace (#8795) Localized file check-in by OneLocBuild Task (#8815) [Xamarin.Android.Build.Tasks] Make all assemblies RID-specific (#8478) Localized file check-in by OneLocBuild Task (#8813) [Xamarin.Android.Build.Tasks] %(AndroidAsset.AssetPack) Support (#8631) [runtime] Remove the last vestiges of desktop builds (#8810) [ci] Don't auto-retry APK test suites. (#8811) [Microsoft.Android.Templates] Update EN l10n template strings (#8808) Bump to xamarin/Java.Interop/main@651de42 (#8809) [Mono.Android] is now "trimming safe" (#8778) [Mono.Android] Fix missing enum issues that cause BG8800 warnings. (#8707) Bump external/Java.Interop from `3436a30` to `5bca8ad` (#8803) Bump to xamarin/monodroid@77124dc1 (#8804) Bump to dotnet/installer@e911f5c82c 9.0.100-preview.3.24161.2 (#8802) Bump to xamarin/Java.Interop/main@3436a30 (#8799)
* main: LEGO: Merge pull request 8818 Bump to dotnet/installer@b40c44502d 9.0.100-preview.3.24165.20 (#8817) Bump com.android.tools:r8 from 8.2.47 to 8.3.37 (#8816) [Mono.Android] Prevent NullPointerException in TranslateStackTrace (#8795) Localized file check-in by OneLocBuild Task (#8815) [Xamarin.Android.Build.Tasks] Make all assemblies RID-specific (#8478) Localized file check-in by OneLocBuild Task (#8813) [Xamarin.Android.Build.Tasks] %(AndroidAsset.AssetPack) Support (#8631)
* main: (99 commits) LEGO: Merge pull request 8818 Bump to dotnet/installer@b40c44502d 9.0.100-preview.3.24165.20 (#8817) Bump com.android.tools:r8 from 8.2.47 to 8.3.37 (#8816) [Mono.Android] Prevent NullPointerException in TranslateStackTrace (#8795) Localized file check-in by OneLocBuild Task (#8815) [Xamarin.Android.Build.Tasks] Make all assemblies RID-specific (#8478) Localized file check-in by OneLocBuild Task (#8813) [Xamarin.Android.Build.Tasks] %(AndroidAsset.AssetPack) Support (#8631) [runtime] Remove the last vestiges of desktop builds (#8810) [ci] Don't auto-retry APK test suites. (#8811) [Microsoft.Android.Templates] Update EN l10n template strings (#8808) Bump to xamarin/Java.Interop/main@651de42 (#8809) [Mono.Android] is now "trimming safe" (#8778) [Mono.Android] Fix missing enum issues that cause BG8800 warnings. (#8707) Bump external/Java.Interop from `3436a30` to `5bca8ad` (#8803) Bump to xamarin/monodroid@77124dc1 (#8804) Bump to dotnet/installer@e911f5c82c 9.0.100-preview.3.24161.2 (#8802) Bump to xamarin/Java.Interop/main@3436a30 (#8799) [templates] Remove redundant "template" from display name. (#8773) Bump to xamarin/Java.Interop/main@a7e09b7 (#8793) ...
* main: [ci] Use managed identity for ApiScan (#8823) [Xamarin.Android.Build.Tasks] DTBs should not rm generator output (#8706) [Xamarin.Android.Build.Tasks] Bump to NuGet 6.7.1 (#8833) $(AndroidPackVersionSuffix)=preview.4; net9 is 34.99.0.preview.4 (#8831) Localized file check-in by OneLocBuild Task (#8824) [Xamarin.Android.Build.Tasks] Enable POM verification features. (#8649) [runtime] Optionally disable inlining (#8798) Fix assembly count when satellite assemblies are present (#8790) [One .NET] new "greenfield" projects are trimmed by default (#8805) Localized file check-in by OneLocBuild Task (#8819) LEGO: Merge pull request 8820 LEGO: Merge pull request 8818 Bump to dotnet/installer@b40c44502d 9.0.100-preview.3.24165.20 (#8817) Bump com.android.tools:r8 from 8.2.47 to 8.3.37 (#8816) [Mono.Android] Prevent NullPointerException in TranslateStackTrace (#8795) Localized file check-in by OneLocBuild Task (#8815) [Xamarin.Android.Build.Tasks] Make all assemblies RID-specific (#8478) Localized file check-in by OneLocBuild Task (#8813)
Context: #8788 (comment)
Context: https://developer.android.com/reference/java/lang/StackTraceElement?hl=en#StackTraceElement(java.lang.String,%20java.lang.String,%20java.lang.String,%20int)
Java.Lang.StackTraceElementconstructor requires thedeclaringClassand
methodNameparameters to never benull. Pass the stringUnknownwhenever any of this information is missing from the managedstack frame.
Additionally, the
lineNumberparameter is now set to-2if we thinka stack frame points to native code.