Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Mono.Android] handle exceptions in RegisterNativeMembers
Context: dotnet/maui#4262 `dotnet new maui-blazor` crashes at runtime, if you do: dotnet build -t:Run -c Release You can turn *off* the linker to solve this issue: dotnet build -t:Run -c Release -p:AndroidLinkMode=None (or `PublishTrimmed=false`) The app crashes in way that you get a native crash: backtrace: #00 pc 000000000065d8fc /apex/com.android.art/lib64/libart.so (void art::StackVisitor::WalkStack<(art::StackVisitor::CountTransitions)0>(bool)+156) (BuildId: 7fbaf2a1a3317bd634b00eb90e32291e) #1 pc 000000000069b25d /apex/com.android.art/lib64/libart.so (art::Thread::GetCurrentMethod(unsigned int*, bool, bool) const+157) (BuildId: 7fbaf2a1a3317bd634b00eb90e32291e) #2 pc 0000000000430fed /apex/com.android.art/lib64/libart.so (art::JNI<false>::FindClass(_JNIEnv*, char const*)+765) (BuildId: 7fbaf2a1a3317bd634b00eb90e32291e) #3 pc 0000000000047e5a /data/app/~~0Qm6D1S0sO3f1lwfakN0PA==/com.companyname.mauiapp2-08UokVCH5k_PlbZEH_hhkA==/split_config.x86_64.apk!libmono-android.release.so (offset 0x11e000) (java_interop_jnienv_find_class+26) (BuildId: 3d04f8b946590175e97b89aee2e3b19ceed4b524) #4 pc 00000000000128ac <anonymous:41640000> After much investigation... We found that `Java.IO.InputStreamHandler.GetReadHandler()` was linked away. This is because: 1. `Mono.Android.dll` has it's Java stubs precompiled into `mono.android.jar` and `mono.android.dex`. 2. Since `Mono.Android.dll` doesn't go through `GenerateJavaStubs`, the linker has no way to know if the missing method is used -- it is only called from Java in the crashing app. To make the crash better, we need to `try-catch` *all* exceptions in `RegisterNativeMembers()` and pass them to `AndroidRuntime.RaisePendingException()`. This is because `RegisterNativeMembers()` is called directly from Java. Now the crash shows: 01-26 12:20:20.290 29264 29264 I MonoDroid: Android.Runtime.JavaProxyThrowable: Exception_WasThrown, Android.Runtime.JavaProxyThrowable 01-26 12:20:20.290 29264 29264 I MonoDroid: 01-26 12:20:20.290 29264 29264 I MonoDroid: --- End of managed Android.Runtime.JavaProxyThrowable stack trace --- 01-26 12:20:20.290 29264 29264 I MonoDroid: android.runtime.JavaProxyThrowable: System.ArgumentException: Arg_DlgtTargMeth 01-26 12:20:20.290 29264 29264 I MonoDroid: at System.Delegate.CreateDelegate(Type , Type , String , Boolean , Boolean ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at System.Delegate.CreateDelegate(Type , Type , String ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.AndroidTypeManager.RegisterNativeMembers(JniType , Type , String ) 01-26 12:20:20.290 29264 29264 I MonoDroid: --- End of stack trace from previous location --- 01-26 12:20:20.290 29264 29264 I MonoDroid: at Java.Interop.JniEnvironment.StaticMethods.CallStaticObjectMethod(JniObjectReference , JniMethodInfo , JniArgumentValue* ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.JNIEnv.CallStaticObjectMethod(IntPtr , IntPtr , JValue* ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.JNIEnv.CallStaticObjectMethod(IntPtr , IntPtr , JValue[] ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.JNIEnv.FindClass(String ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.JNIEnv.AllocObject(String ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.JNIEnv.StartCreateInstance(String , String , JValue* ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.JNIEnv.StartCreateInstance(String , String , JValue[] ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.InputStreamAdapter..ctor(Stream ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.InputStreamAdapter.ToLocalJniHandle(Stream ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Webkit.WebResourceResponse..ctor(String , String , Int32 , String , IDictionary`2 , Stream ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Microsoft.AspNetCore.Components.WebView.Maui.WebKitWebViewClient.ShouldInterceptRequest(WebView view, IWebResourceRequest request) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Webkit.WebViewClient.n_ShouldInterceptRequest_Landroid_webkit_WebView_Landroid_webkit_WebResourceRequest_(IntPtr , IntPtr , IntPtr , IntPtr ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at crc64d693e2d9159537db.WebKitWebViewClient.n_shouldInterceptRequest(Native Method) 01-26 12:20:20.290 29264 29264 I MonoDroid: at crc64d693e2d9159537db.WebKitWebViewClient.shouldInterceptRequest(WebKitWebViewClient.java:39) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Rr.a(chromium-TrichromeWebViewGoogle.apk-stable-410410686:16) 01-26 12:20:20.290 29264 29264 I MonoDroid: at org.chromium.android_webview.AwContentsBackgroundThreadClient.shouldInterceptRequestFromNative(chromium-TrichromeWebViewGoogle.apk-stable-410410686:2) 01-26 12:20:20.290 29264 29264 I MonoDroid: 01-26 12:20:20.290 29264 29264 I MonoDroid: --- End of managed Android.Runtime.JavaProxyThrowable stack trace --- 01-26 12:20:20.290 29264 29264 I MonoDroid: android.runtime.JavaProxyThrowable: System.ArgumentException: Arg_DlgtTargMeth 01-26 12:20:20.290 29264 29264 I MonoDroid: at System.Delegate.CreateDelegate(Type , Type , String , Boolean , Boolean ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at System.Delegate.CreateDelegate(Type , Type , String ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.AndroidTypeManager.RegisterNativeMembers(JniType , Type , String ) 01-26 12:20:20.290 29264 29264 I MonoDroid: --- End of stack trace from previous location --- 01-26 12:20:20.290 29264 29264 I MonoDroid: at Java.Interop.JniEnvironment.StaticMethods.CallStaticObjectMethod(JniObjectReference , JniMethodInfo , JniArgumentValue* ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.JNIEnv.CallStaticObjectMethod(IntPtr , IntPtr , JValue* ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.JNIEnv.CallStaticObjectMethod(IntPtr , IntPtr , JValue[] ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.JNIEnv.FindClass(String ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.JNIEnv.AllocObject(String ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.JNIEnv.StartCreateInstance(String , String , JValue* ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.JNIEnv.StartCreateInstance(String , String , JValue[] ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.InputStreamAdapter..ctor(Stream ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Runtime.InputStreamAdapter.ToLocalJniHandle(Stream ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Webkit.WebResourceResponse..ctor(String , String , Int32 , String , IDictionary`2 , Stream ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Microsoft.AspNetCore.Components.WebView.Maui.WebKitWebViewClient.ShouldInterceptRequest(WebView view, IWebResourceRequest request) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Android.Webkit.WebViewClient.n_ShouldInterceptRequest_Landroid_webkit_WebView_Landroid_webkit_WebResourceRequest_(IntPtr , IntPtr , IntPtr , IntPtr ) 01-26 12:20:20.290 29264 29264 I MonoDroid: at crc64d693e2d9159537db.WebKitWebViewClient.n_shouldInterceptRequest(Native Method) 01-26 12:20:20.290 29264 29264 I MonoDroid: at crc64d693e2d9159537db.WebKitWebViewClient.shouldInterceptRequest(WebKitWebViewClient.java:39) 01-26 12:20:20.290 29264 29264 I MonoDroid: at Rr.a(chromium-TrichromeWebViewGoogle.apk-stable-410410686:16) 01-26 12:20:20.290 29264 29264 I MonoDroid: at org.chromium.android_webview.AwContentsBackgroundThreadClient.shouldInterceptRequestFromNative(chromium-TrichromeWebViewGoogle.apk-stable-410410686:2) This is much easier to reason about, and will save us time in the future. A fix to the actual linker problem will be coming in another PR.
- Loading branch information