-
Notifications
You must be signed in to change notification settings - Fork 533
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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. |
for (int i = 0; i < frames.Length; i++) { | ||
StackFrame managedFrame = frames[i]; | ||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.StackTraceElement
constructor requires thedeclaringClass
and
methodName
parameters to never benull
. Pass the stringUnknown
whenever any of this information is missing from the managedstack frame.
Additionally, the
lineNumber
parameter is now set to-2
if we thinka stack frame points to native code.