-
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
Improve JavaProxyThrowable integration #1198
Labels
Area: Mono.Android
Issues with the Android API binding (Mono.Android.dll).
Milestone
Comments
jonpryor
added a commit
that referenced
this issue
Apr 26, 2021
Xamarin.Android v11.3.0 will be shipped as part of Visual Studio 2019 16.10 Preview 3 and subsequent releases. Changes: mono/debugger-libs@8bf09ce...08268b7 * mono/debugger-libs@08268b7: Add Module.ApplyChanges (#342) * mono/debugger-libs@1b5a55a: Fix assembly version after converting projects to SDK style Changes: dotnet/java-interop@f9faaab...f39db25 * dotnet/java-interop@f39db25c: Branching for d16-10. * dotnet/java-interop@f4e68b5b: [generator] Separate metadata fixup step from parsing step. (#822) Changes: xamarin/monodroid@76c04cd...69e9111 * xamarin/monodroid@69e911139: Branching for d16-10. * xamarin/monodroid@9f9ee378c: [tools/msbuild] Missing translations for XA0135 (#1198) Changes: dotnet/android-tools@d92fc3e...c5732a0 * dotnet/android-tools@c5732a0: [Xamarin.Android.Tools.AndroidSdk] Support Microsoft Dist JDK (#117) * dotnet/android-tools@52ef989: [Xamarin.Android.Tools.AndroidSdk] Fix CS0168 warning (#116)
jonpryor
added a commit
that referenced
this issue
Apr 26, 2021
Xamarin.Android v11.3.0 will be shipped as part of Visual Studio 2019 16.10 Preview 3 and subsequent releases. Changes: mono/debugger-libs@8bf09ce...08268b7 * mono/debugger-libs@08268b7: Add Module.ApplyChanges (#342) * mono/debugger-libs@1b5a55a: Fix assembly version after converting projects to SDK style Changes: dotnet/java-interop@f9faaab...f39db25 * dotnet/java-interop@f39db25c: Branching for d16-10. * dotnet/java-interop@f4e68b5b: [generator] Separate metadata fixup step from parsing step. (#822) Changes: xamarin/monodroid@76c04cd...69e9111 * xamarin/monodroid@69e911139: Branching for d16-10. * xamarin/monodroid@9f9ee378c: [tools/msbuild] Missing translations for XA0135 (#1198) Changes: dotnet/android-tools@d92fc3e...c5732a0 * dotnet/android-tools@c5732a0: [Xamarin.Android.Tools.AndroidSdk] Support Microsoft Dist JDK (#117) * dotnet/android-tools@52ef989: [Xamarin.Android.Tools.AndroidSdk] Fix CS0168 warning (#116)
jonpryor
pushed a commit
that referenced
this issue
Jun 10, 2021
Changes: xamarin/monodroid@76c04cd...1f2ce15 * xamarin/monodroid@1f2ce1562: [tools/msbuild] only run _GetPrimaryCpuAbi for Fast Dev (#1208) * xamarin/monodroid@691310ede: Bump android-sdk-installer to use Mono.Unix (#1207) * xamarin/monodroid@48843fcb2: [tools/msbuild] <GetPrimaryCpuAbi/> selects backup RIDs for .NET 6 (#1205) * xamarin/monodroid@4af48f54b: [tools/fastdev] Add error checking when writing data to disk. (#1204) * xamarin/monodroid@65b7b2dd4: [tools/fastdev] Rework Unix timestamp calculation code in xamarin.find. (#1202) * xamarin/monodroid@401f170e9: [build] fix `dotnet tool install` command (#1203) * xamarin/monodroid@a879b250b: Bump to 032d840, xamarin/androidtools@355d015 (#1199) * xamarin/monodroid@9f9ee378c: [tools/msbuild] Missing translations for XA0135 (#1198) Changes: dotnet/android-tools@683f375...49936d6 * dotnet/android-tools@49936d6: Merge pull request #124 from xamarin/update-libzipsharp * dotnet/android-tools@ef78dfc: Bump LibZipSharp to 2.0.0-alpha6 * dotnet/android-tools@e3d708c: [BaseTasks] fix `\`-delimited paths on macOS (#122) * dotnet/android-tools@bdcf899: Reference the new Mono.Unix nuget (#123) * dotnet/android-tools@90d7621: [BaseTasks] add ABI detection for RIDs (#121) * dotnet/android-tools@79e3b97: [JdkInfo] handle invalid XML from /usr/libexec/java_home (#120) * dotnet/android-tools@81519fe: Add SECURITY.md (#119) Xamarin.Android uses the Mono's Mono.Posix assembly on Unix machines to perform tasks not possible with BCL classes, provided by the [`Mono.Posix.NETStandard` NuGet][0]. The `Mono.Posix` source has been extracted into the [mono/mono.posix repo][1], which is used to build the new [`Mono.Unix` NuGet package][2]. Update the xamarin/xamarin-android repo -- and various dependencies -- to use the `Mono.Unix` package instead of `Mono.Posix.NETStandard`. This includes the [`Xamarin.LibZipSharp` NuGet][3], as of dotnet/android-libzipsharp@cf5e33c6. `Mono.Unix` no longer uses the older `libMonoPosixHelper` dynamic library, replaced by a new `libMono.Unix` native library. Unfortunately, this change broke a number of tests since the `Mono.Unix.dll` assembly was no longer able to find its companion native shared library. While the `Mono.Posix.NETStandard` NuGet package provides the `libMonoPosixHelper` native library, in practice the *actual* `libMonoPosixHelper` that was used was the "system" library included with the system mono. `Mono.Unix`'s new native helper library, however, must be taken from the NuGet and both the Mono and dotnet runtimes must be told where to load the library from once a P/Invoke into `Mono.Unix` is encountered in managed code. The native library is copied from the NuGet to the referencing application's output directory and it should be loaded from there. This proved to be easy for the "legacy" Mono: a simple [`dllmap` configuration][4] and everything works as it should. With `dotnet` however, dllmap doesn't work. `dotnet` has instead a number of mechanisms to configure where the native libraries can be found (5 I think). Unfortunately, the mechanisms either require that a main executable of the application calls the APIs on entry (e.g. in the `Main()` method) or that a JSON configuration file is provided for the application, telling the runtime where the native libraries reside. In case of `Xamarin.Android.Build.Tasks` there is no main executable we can configure, since it works in the MSBuild context, providing tasks and utilities to build Xamarin.Android apps. In this instance, `dotnet` could be persuaded to find the libraries by calling one of the 5 APIs. The problem with this approach, however, is that this action would have to be performed at **every** possible entry point to the `Xamarin.Android.Build.Tasks` assembly, since any of them could be used as the first one. While certainly possible, it would be both fragile and an unnecessary maintenance burden. Instead, a simpler (albeit a bit kludgy) solution was chosen: the `src/Xamarin.Android.Build.Tasks` build process now takes care of generating a fat (multi-architecture) binary for macOS hosts (including `x86-64` and `arm64` architectures) using the `lipo` utility, then it copies the resulting binary to the same directory where `Xamarin.Android.Build.Tasks.dll` and `Mono.Unix.dll` live. The Linux shared library is also copied to the same location. The `dotnet` runtime is able to find and load shared libraries that are in the same directory as the assembly that needs them and everything works as expected. [0]: https://www.nuget.org/packages/Mono.Posix.NETStandard/5.20.1-preview [1]: https://github.com/mono/mono.posix [2]: https://www.nuget.org/packages/Mono.Unix/ [3]: https://www.nuget.org/packages/Xamarin.LibZipSharp [4]: https://www.mono-project.com/docs/advanced/pinvoke/dllmap/
No plans to get this worked on? :( I get from time to time crashes that are only seen in GooglePlayConsole which cannot be captured by
|
knocte
added a commit
to nblockchain/geewallet
that referenced
this issue
Feb 20, 2022
This was observed on Android[1], might have been introduced in this commit: e1e0531 [1] Can only be reproduced when the date is modified, but not when the date is not modified (and thus the "date has not been modified" dialog kicks in). And somehow we're not getting a Sentry report on this (likely because of dotnet/android#1198). There's a Java exception logged in GooglePlayConsole that may be related to this crash: ``` android.runtime.JavaProxyThrowable android.runtime.JavaProxyThrowable: at Java.Interop.JniEnvironment+InstanceMethods.CallObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0006e] in <52f10d87dbbb4d09a29042ac70363317>:0 at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0002a] in <52f10d87dbbb4d09a29042ac70363317>:0 at AndroidX.AppCompat.App.AlertDialog+Builder.Create () [0x0000a] in <6d3c6b73981a41788429b90c0b0983c0>:0 at Xamarin.Forms.Platform.Android.PopupManager+PopupRequestHelper+DialogBuilder.Create () [0x00008] in <04c545f414d24a37af95d995791bb9a9>:0 at Xamarin.Forms.Platform.Android.PopupManager+PopupRequestHelper.OnAlertRequested (Xamarin.Forms.Page sender, Xamarin.Forms.Internals.AlertArguments arguments) [0x00028] in <04c545f414d24a37af95d995791bb9a9>:0 at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&) at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in <5229225a94454bc59c40710c26e93043>:0 at [email protected] (System.Runtime.ExceptionServices.ExceptionDispatchInfo edi) [0x00000] in <f1f01bf047f43136b90da0590c91572c> at Microsoft.FSharp.Control.Trampoline.Execute (Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] firstAction) [0x0009c] in <f1f01bf047f43136b90da0590c91572c>:0 at Microsoft.FSharp.Control.TrampolineHolder.ExecuteWithTrampoline (Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] firstAction) [0x00031] in <f1f01bf047f43136b90da0590c91572c>:0 at <StartupCode$FSharp-Core>[email protected] (System.Object o) [0x00017] in <f1f01bf047f43136b90da0590c91572c>:0 at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object state) [0x00007] in <5229225a94454bc59c40710c26e93043>:0 at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00071] in <5229225a94454bc59c40710c26e93043>:0 at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <5229225a94454bc59c40710c26e93043>:0 at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () [0x00021] in <5229225a94454bc59c40710c26e93043>:0 at System.Threading.ThreadPoolWorkQueue.Dispatch () [0x00074] in <5229225a94454bc59c40710c26e93043>:0 at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () [0x00000] in <5229225a94454bc59c40710c26e93043>:0 at mono.java.lang.RunnableImplementor.n_run (Native Method) at mono.java.lang.RunnableImplementor.run (RunnableImplementor.java:30) at android.os.Handler.handleCallback (Handler.java:938) at android.os.Handler.dispatchMessage (Handler.java:99) at android.os.Looper.loopOnce (Looper.java:201) at android.os.Looper.loop (Looper.java:288) at android.app.ActivityThread.main (ActivityThread.java:7839) at java.lang.reflect.Method.invoke (Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1003) ```
grendello
added a commit
to grendello/xamarin-android
that referenced
this issue
Jul 12, 2023
Fixes: dotnet#1198 Given an instance of `System.Exception`, we can use the `System.Diagnostics.StackTrace` class to iterate over the list of managed stack frames, translating each of them to equivalent `Java.Lang.StackTraceElement` and afterwards passing the entire collection to `Java.Lang.Throwable.SetStackTrace`.
grendello
added
Area: Mono.Android
Issues with the Android API binding (Mono.Android.dll).
and removed
Area: App Runtime
Issues in `libmonodroid.so`.
labels
Jul 12, 2023
jonpryor
pushed a commit
that referenced
this issue
Aug 23, 2023
…8185) Context: #1198 Context: #1188 (comment) Context: #4877 Context: #4927 (comment) What happens with unhandled exceptions? throw new InvalidOperationException ("oops!"); This is a surprisingly complicated question: If this happens when a debugger is attached, the debugger will get a "first chance notification" at the `throw` site. If execution continues, odds are high that the app will abort if there is a JNI transition in the callstack. If no debugger is attached, then it depends on which thread threw the unhandled exception. If the thread which threw the unhandled exception is a .NET Thread: static void ThrowFromAnotherManagedThread() { var t = new System.Threading.Thread(() => { throw new new Java.Lang.Error ("from another thread?!"); }); t.Start (); t.Join (); } Then .NET will report the unhandled exception, *and* the app will restart: F mono-rt : [ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidOperationException: oops! F mono-rt : at android_unhandled_exception.MainActivity.<>c.<ThrowFromAnotherManagedThread>b__1_0() F mono-rt : at System.Threading.Thread.StartCallback() # app restarts If the thread which threw the unhandled exception is a *Java* thread, which could be the UI thread (e.g. thrown from an `Activity.OnCreate()` override) or via a `Java.Lang.Thread` instance: static void ThrowFromAnotherJavaThread() { var t = new Java.Lang.Thread(() => { throw new InvalidOperationException ("oops!"); }); t.Start (); t.Join (); } Then .NET will report the unhandled exception, *and* the app will *not* restart (which differs from using .NET threads): E AndroidRuntime: Process: com.companyname.android_unhandled_exception, PID: 5436 E AndroidRuntime: android.runtime.JavaProxyThrowable: System.InvalidOperationException: oops! E AndroidRuntime: at android_unhandled_exception.MainActivity.<>c.<ThrowFromAnotherJavaThread>b__2_0() E AndroidRuntime: at Java.Lang.Thread.RunnableImplementor.Run() E AndroidRuntime: at Java.Lang.IRunnableInvoker.n_Run(IntPtr , IntPtr ) E AndroidRuntime: at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V , IntPtr , IntPtr ) E AndroidRuntime: at mono.java.lang.RunnableImplementor.n_run(Native Method) E AndroidRuntime: at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31) E AndroidRuntime: at java.lang.Thread.run(Thread.java:1012) I MonoDroid: Android.Runtime.JavaProxyThrowable: Exception_WasThrown, Android.Runtime.JavaProxyThrowable I MonoDroid: I MonoDroid: --- End of managed Android.Runtime.JavaProxyThrowable stack trace --- I MonoDroid: android.runtime.JavaProxyThrowable: System.InvalidOperationException: oops! I MonoDroid: at android_unhandled_exception.MainActivity.<>c.<ThrowFromAnotherJavaThread>b__2_0() I MonoDroid: at Java.Lang.Thread.RunnableImplementor.Run() I MonoDroid: at Java.Lang.IRunnableInvoker.n_Run(IntPtr , IntPtr ) I MonoDroid: at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V , IntPtr , IntPtr ) I MonoDroid: at mono.java.lang.RunnableImplementor.n_run(Native Method) I MonoDroid: at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31) I MonoDroid: at java.lang.Thread.run(Thread.java:1012) I MonoDroid: I MonoDroid: --- End of managed Android.Runtime.JavaProxyThrowable stack trace --- I MonoDroid: android.runtime.JavaProxyThrowable: System.InvalidOperationException: oops! I MonoDroid: at android_unhandled_exception.MainActivity.<>c.<ThrowFromAnotherJavaThread>b__2_0() I MonoDroid: at Java.Lang.Thread.RunnableImplementor.Run() I MonoDroid: at Java.Lang.IRunnableInvoker.n_Run(IntPtr , IntPtr ) I MonoDroid: at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V , IntPtr , IntPtr ) I MonoDroid: at mono.java.lang.RunnableImplementor.n_run(Native Method) I MonoDroid: at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31) I MonoDroid: at java.lang.Thread.run(Thread.java This "works", until we enter the world of crash logging for later diagnosis and fixing. The problem with our historical approach is that we would "stuff" the .NET stack trace into the "message" of the Java-side `Throwable` instance, and the "message" may not be transmitted as part of the crash logging! (This is noticeable by the different indentation levels for the `at …` lines in the crash output. Three space indents are from the `Throwable.getMessage()` output, while four space indents are from the Java-side stack trace.) We *think* that we can improve this by replacing the Java-side stack trace with a "merged" stack trace which includes both the Java-side and .NET-side stack traces. This does nothing for unhandled exceptions on .NET threads, but does alter the output from Java threads: E AndroidRuntime: FATAL EXCEPTION: Thread-3 E AndroidRuntime: Process: com.companyname.android_unhandled_exception, PID: 12321 E AndroidRuntime: android.runtime.JavaProxyThrowable: [System.InvalidOperationException]: oops! E AndroidRuntime: at android_unhandled_exception.MainActivity+<>c.<ThrowFromAnotherJavaThread>b__2_0(Unknown Source:0) E AndroidRuntime: at Java.Lang.Thread+RunnableImplementor.Run(Unknown Source:0) E AndroidRuntime: at Java.Lang.IRunnableInvoker.n_Run(Unknown Source:0) E AndroidRuntime: at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(Unknown Source:0) E AndroidRuntime: at mono.java.lang.RunnableImplementor.n_run(Native Method) E AndroidRuntime: at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31) E AndroidRuntime: at java.lang.Thread.run(Thread.java:1012) I MonoDroid: UNHANDLED EXCEPTION: I MonoDroid: Android.Runtime.JavaProxyThrowable: Exception_WasThrown, Android.Runtime.JavaProxyThrowable I MonoDroid: I MonoDroid: --- End of managed Android.Runtime.JavaProxyThrowable stack trace --- I MonoDroid: android.runtime.JavaProxyThrowable: [System.InvalidOperationException]: oops! I MonoDroid: at android_unhandled_exception.MainActivity+<>c.<ThrowFromAnotherJavaThread>b__2_0(Unknown Source:0) I MonoDroid: at Java.Lang.Thread+RunnableImplementor.Run(Unknown Source:0) I MonoDroid: at Java.Lang.IRunnableInvoker.n_Run(Unknown Source:0) I MonoDroid: at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(Unknown Source:0) I MonoDroid: at mono.java.lang.RunnableImplementor.n_run(Native Method) I MonoDroid: at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31) I MonoDroid: at java.lang.Thread.run(Thread.java:1012) I MonoDroid: I MonoDroid: --- End of managed Android.Runtime.JavaProxyThrowable stack trace --- I MonoDroid: android.runtime.JavaProxyThrowable: [System.InvalidOperationException]: oops! I MonoDroid: at android_unhandled_exception.MainActivity+<>c.<ThrowFromAnotherJavaThread>b__2_0(Unknown Source:0) I MonoDroid: at Java.Lang.Thread+RunnableImplementor.Run(Unknown Source:0) I MonoDroid: at Java.Lang.IRunnableInvoker.n_Run(Unknown Source:0) I MonoDroid: at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(Unknown Source:0) I MonoDroid: at mono.java.lang.RunnableImplementor.n_run(Native Method) I MonoDroid: at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31) I MonoDroid: at java.lang.Thread.run(Thread.java:1012) Note how `at …` is always a four-space indent and always lines up. *Hopefully* this means that crash loggers can provide more useful information. TODO: * Create an "end-to-end" test which uses an actual crash logger (which one?) in order to better understand what the "end user" experience is. * The "merged" stack trace always places the managed stack trace above the Java-side stack trace. This means things will look "weird"/"wrong" if you have an *intermixed* stack trace, e.g. (Java code calls .NET code which calls Java code)+ which eventually throws from .NET.
jonathanpeppers
pushed a commit
that referenced
this issue
Aug 23, 2023
…8185) Context: #1198 Context: #1188 (comment) Context: #4877 Context: #4927 (comment) What happens with unhandled exceptions? throw new InvalidOperationException ("oops!"); This is a surprisingly complicated question: If this happens when a debugger is attached, the debugger will get a "first chance notification" at the `throw` site. If execution continues, odds are high that the app will abort if there is a JNI transition in the callstack. If no debugger is attached, then it depends on which thread threw the unhandled exception. If the thread which threw the unhandled exception is a .NET Thread: static void ThrowFromAnotherManagedThread() { var t = new System.Threading.Thread(() => { throw new new Java.Lang.Error ("from another thread?!"); }); t.Start (); t.Join (); } Then .NET will report the unhandled exception, *and* the app will restart: F mono-rt : [ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidOperationException: oops! F mono-rt : at android_unhandled_exception.MainActivity.<>c.<ThrowFromAnotherManagedThread>b__1_0() F mono-rt : at System.Threading.Thread.StartCallback() # app restarts If the thread which threw the unhandled exception is a *Java* thread, which could be the UI thread (e.g. thrown from an `Activity.OnCreate()` override) or via a `Java.Lang.Thread` instance: static void ThrowFromAnotherJavaThread() { var t = new Java.Lang.Thread(() => { throw new InvalidOperationException ("oops!"); }); t.Start (); t.Join (); } Then .NET will report the unhandled exception, *and* the app will *not* restart (which differs from using .NET threads): E AndroidRuntime: Process: com.companyname.android_unhandled_exception, PID: 5436 E AndroidRuntime: android.runtime.JavaProxyThrowable: System.InvalidOperationException: oops! E AndroidRuntime: at android_unhandled_exception.MainActivity.<>c.<ThrowFromAnotherJavaThread>b__2_0() E AndroidRuntime: at Java.Lang.Thread.RunnableImplementor.Run() E AndroidRuntime: at Java.Lang.IRunnableInvoker.n_Run(IntPtr , IntPtr ) E AndroidRuntime: at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V , IntPtr , IntPtr ) E AndroidRuntime: at mono.java.lang.RunnableImplementor.n_run(Native Method) E AndroidRuntime: at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31) E AndroidRuntime: at java.lang.Thread.run(Thread.java:1012) I MonoDroid: Android.Runtime.JavaProxyThrowable: Exception_WasThrown, Android.Runtime.JavaProxyThrowable I MonoDroid: I MonoDroid: --- End of managed Android.Runtime.JavaProxyThrowable stack trace --- I MonoDroid: android.runtime.JavaProxyThrowable: System.InvalidOperationException: oops! I MonoDroid: at android_unhandled_exception.MainActivity.<>c.<ThrowFromAnotherJavaThread>b__2_0() I MonoDroid: at Java.Lang.Thread.RunnableImplementor.Run() I MonoDroid: at Java.Lang.IRunnableInvoker.n_Run(IntPtr , IntPtr ) I MonoDroid: at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V , IntPtr , IntPtr ) I MonoDroid: at mono.java.lang.RunnableImplementor.n_run(Native Method) I MonoDroid: at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31) I MonoDroid: at java.lang.Thread.run(Thread.java:1012) I MonoDroid: I MonoDroid: --- End of managed Android.Runtime.JavaProxyThrowable stack trace --- I MonoDroid: android.runtime.JavaProxyThrowable: System.InvalidOperationException: oops! I MonoDroid: at android_unhandled_exception.MainActivity.<>c.<ThrowFromAnotherJavaThread>b__2_0() I MonoDroid: at Java.Lang.Thread.RunnableImplementor.Run() I MonoDroid: at Java.Lang.IRunnableInvoker.n_Run(IntPtr , IntPtr ) I MonoDroid: at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V , IntPtr , IntPtr ) I MonoDroid: at mono.java.lang.RunnableImplementor.n_run(Native Method) I MonoDroid: at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31) I MonoDroid: at java.lang.Thread.run(Thread.java This "works", until we enter the world of crash logging for later diagnosis and fixing. The problem with our historical approach is that we would "stuff" the .NET stack trace into the "message" of the Java-side `Throwable` instance, and the "message" may not be transmitted as part of the crash logging! (This is noticeable by the different indentation levels for the `at …` lines in the crash output. Three space indents are from the `Throwable.getMessage()` output, while four space indents are from the Java-side stack trace.) We *think* that we can improve this by replacing the Java-side stack trace with a "merged" stack trace which includes both the Java-side and .NET-side stack traces. This does nothing for unhandled exceptions on .NET threads, but does alter the output from Java threads: E AndroidRuntime: FATAL EXCEPTION: Thread-3 E AndroidRuntime: Process: com.companyname.android_unhandled_exception, PID: 12321 E AndroidRuntime: android.runtime.JavaProxyThrowable: [System.InvalidOperationException]: oops! E AndroidRuntime: at android_unhandled_exception.MainActivity+<>c.<ThrowFromAnotherJavaThread>b__2_0(Unknown Source:0) E AndroidRuntime: at Java.Lang.Thread+RunnableImplementor.Run(Unknown Source:0) E AndroidRuntime: at Java.Lang.IRunnableInvoker.n_Run(Unknown Source:0) E AndroidRuntime: at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(Unknown Source:0) E AndroidRuntime: at mono.java.lang.RunnableImplementor.n_run(Native Method) E AndroidRuntime: at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31) E AndroidRuntime: at java.lang.Thread.run(Thread.java:1012) I MonoDroid: UNHANDLED EXCEPTION: I MonoDroid: Android.Runtime.JavaProxyThrowable: Exception_WasThrown, Android.Runtime.JavaProxyThrowable I MonoDroid: I MonoDroid: --- End of managed Android.Runtime.JavaProxyThrowable stack trace --- I MonoDroid: android.runtime.JavaProxyThrowable: [System.InvalidOperationException]: oops! I MonoDroid: at android_unhandled_exception.MainActivity+<>c.<ThrowFromAnotherJavaThread>b__2_0(Unknown Source:0) I MonoDroid: at Java.Lang.Thread+RunnableImplementor.Run(Unknown Source:0) I MonoDroid: at Java.Lang.IRunnableInvoker.n_Run(Unknown Source:0) I MonoDroid: at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(Unknown Source:0) I MonoDroid: at mono.java.lang.RunnableImplementor.n_run(Native Method) I MonoDroid: at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31) I MonoDroid: at java.lang.Thread.run(Thread.java:1012) I MonoDroid: I MonoDroid: --- End of managed Android.Runtime.JavaProxyThrowable stack trace --- I MonoDroid: android.runtime.JavaProxyThrowable: [System.InvalidOperationException]: oops! I MonoDroid: at android_unhandled_exception.MainActivity+<>c.<ThrowFromAnotherJavaThread>b__2_0(Unknown Source:0) I MonoDroid: at Java.Lang.Thread+RunnableImplementor.Run(Unknown Source:0) I MonoDroid: at Java.Lang.IRunnableInvoker.n_Run(Unknown Source:0) I MonoDroid: at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(Unknown Source:0) I MonoDroid: at mono.java.lang.RunnableImplementor.n_run(Native Method) I MonoDroid: at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31) I MonoDroid: at java.lang.Thread.run(Thread.java:1012) Note how `at …` is always a four-space indent and always lines up. *Hopefully* this means that crash loggers can provide more useful information. TODO: * Create an "end-to-end" test which uses an actual crash logger (which one?) in order to better understand what the "end user" experience is. * The "merged" stack trace always places the managed stack trace above the Java-side stack trace. This means things will look "weird"/"wrong" if you have an *intermixed* stack trace, e.g. (Java code calls .NET code which calls Java code)+ which eventually throws from .NET.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Note: This should be done in the Java.Interop repo, and then we should ditch
Android.Runtime.JavaProxyThrowable
in favor ofJava.Interop.JavaProxyThrowable
.Related: Issue #1188.
It appears that
JavaProxyThrowable
doesn't integrate well with Java: if Java code callsThrowable.printStackTrace()
, it might not also print -- or might truncate -- the output ofThrowable.getMessage()
, andThrowable.getMessage()
is whereJavaProxyThrowable
squirrels away the "originating"System.Exception
stack trace.We should update
JavaProxyThrowable
so that it usesThrowable.setStackTrace()
to merge or replace theSystem.Exception
stack frames in with theThrowable
stack frames.I believe that this will in turn improve integration with e.g. HockeyApp and other apps which utilize
Throwable.printStackTrace()
.The text was updated successfully, but these errors were encountered: