Skip to content
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

[android] AppDomain.CurrentDomain.UnhandledException not working in .NET 5/6 #44526

Closed
jonathanpeppers opened this issue Nov 11, 2020 · 13 comments

Comments

@jonathanpeppers
Copy link
Member

Description

I've been working on getting some integration tests working for Android in .NET 5/6, such as:

https://github.com/xamarin/xamarin-android/blob/5369da67a91c71aa646fd2642c71e519ae01cff9/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs#L63-L64

It appears that the AppDomain.CurrentDomain.UnhandledException event doesn't fire in an example such as:

public class MainActivity : Activity
{
	protected override void OnCreate (Bundle bundle)
	{
		base.OnCreate (bundle);

		SetContentView (Resource.Layout.Main);

		AppDomain.CurrentDomain.UnhandledException += (sender, e) => {
			Console.WriteLine ("# Unhandled Exception: sender={0}; e.IsTerminating={1}; e.ExceptionObject={2}",
				sender, e.IsTerminating, e.ExceptionObject);
		};
		throw new Exception ("CRASH");
	}
}

AppDomain.CurrentDomain.UnhandledException seems to work fine in a .NET 5 console app:

https://docs.microsoft.com/dotnet/api/system.appdomain.unhandledexception?view=net-5.0

Configuration

I was using a master build of Xamarin.Android, but I tried these .NET versions:

  • 5.0.100 GA
  • 6.0.100-alpha.1.20555.3

Regression?

No, Android is a new platform.

/cc @marek-safar @akoeplinger

@lambdageek lambdageek added area-VM-meta-mono os-android untriaged New issue has not been triaged by the area owner labels Nov 11, 2020
@ghost
Copy link

ghost commented Nov 11, 2020

Tagging subscribers to this area: @CoffeeFlux
See info in area-owners.md if you want to be subscribed.


Issue meta data

Issue content: # Description

I've been working on getting some integration tests working for Android in .NET 5/6, such as:

https://github.com/xamarin/xamarin-android/blob/5369da67a91c71aa646fd2642c71e519ae01cff9/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs#L63-L64

It appears that the AppDomain.CurrentDomain.UnhandledException event doesn't fire in an example such as:

public class MainActivity : Activity
{
	protected override void OnCreate (Bundle bundle)
	{
		base.OnCreate (bundle);

		SetContentView (Resource.Layout.Main);

		AppDomain.CurrentDomain.UnhandledException += (sender, e) => {
			Console.WriteLine ("# Unhandled Exception: sender={0}; e.IsTerminating={1}; e.ExceptionObject={2}",
				sender, e.IsTerminating, e.ExceptionObject);
		};
		throw new Exception ("CRASH");
	}
}

AppDomain.CurrentDomain.UnhandledException seems to work fine in a .NET 5 console app:

https://docs.microsoft.com/dotnet/api/system.appdomain.unhandledexception?view=net-5.0

Configuration

I was using a master build of Xamarin.Android, but I tried these .NET versions:

  • 5.0.100 GA
  • 6.0.100-alpha.1.20555.3

Regression?

No, Android is a new platform.

/cc @marek-safar @akoeplinger

Issue author: jonathanpeppers
Assignees: -
Milestone: -

@CoffeeFlux
Copy link
Contributor

I think I already fixed this for desktop, so it's strange it doesn't work on Android. There should be a failing runtime test that corresponds to this, but we still don't have issues opened for the failures so I'm not sure where to confirm that. (Related: I still think we really want to get individual issues opened for those failures up sometime soon because of things like this.) cc: @SamMonoRT

@jonathanpeppers
Copy link
Member Author

@CoffeeFlux to double-check, I tried it again with .NET 6.0.100-alpha.1.20555.3, and changed the code to use:

--Console.WriteLine ("# Unhandled Exception: sender={0}; e.IsTerminating={1}; e.ExceptionObject={2}",
++Android.Util.Log.Debug ("Foo", "# Unhandled Exception: sender={0}; e.IsTerminating={1}; e.ExceptionObject={2}",

But I'm not seeing it in adb logcat output.

@marek-safar marek-safar removed the untriaged New issue has not been triaged by the area owner label Nov 11, 2020
@marek-safar marek-safar added this to the 6.0.0 milestone Nov 11, 2020
@SamMonoRT
Copy link
Member

@jonathanpeppers - is this still an issue, and if so, is this really required for 6.0 ?

@jonathanpeppers
Copy link
Member Author

We still have this test disabled:

https://github.com/xamarin/xamarin-android/blob/7c5fab13329ee898fb1562f83576a7ca881f2881/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs#L62-L64

I ran the test just now, and I'm not seeing the UnhandledException event fire.

I would think customers would want this event to work. Various crash reporting tools would use it, such as AppCenter or Raygun.

I get this in the log, but the app seems to abort before the event:

07-09 10:07:07.076  3682  3682 I MonoDroid:   --- End of managed Android.Runtime.JavaProxyThrowable stack trace ---
07-09 10:07:07.076  3682  3682 I MonoDroid: android.runtime.JavaProxyThrowable: System.Exception: CRASH
07-09 10:07:07.076  3682  3682 I MonoDroid:    at UnnamedProject.MainActivity.OnCreate(Bundle bundle) in UnnamedProject.dll:token 0x6000001+0x70
07-09 10:07:07.076  3682  3682 I MonoDroid:    at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_(IntPtr , IntPtr , IntPtr ) in Mono.Android.dll:token 0x60000e6+0x12
07-09 10:07:07.076  3682  3682 I MonoDroid:     at com.xamarin.subscribetoappdomainunhandledexception.MainActivity.n_onCreate(Native Method)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at com.xamarin.subscribetoappdomainunhandledexception.MainActivity.onCreate(MainActivity.java:29)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.Activity.performCreate(Activity.java:7994)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.Activity.performCreate(Activity.java:7978)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3404)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.os.Handler.dispatchMessage(Handler.java:106)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.os.Looper.loop(Looper.java:223)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.ActivityThread.main(ActivityThread.java:7664)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at java.lang.reflect.Method.invoke(Native Method)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
07-09 10:07:07.076  3682  3682 I MonoDroid:
07-09 10:07:07.076  3682  3682 I MonoDroid:   --- End of managed Android.Runtime.JavaProxyThrowable stack trace ---
07-09 10:07:07.076  3682  3682 I MonoDroid: android.runtime.JavaProxyThrowable: System.Exception: CRASH
07-09 10:07:07.076  3682  3682 I MonoDroid:    at UnnamedProject.MainActivity.OnCreate(Bundle bundle) in UnnamedProject.dll:token 0x6000001+0x70
07-09 10:07:07.076  3682  3682 I MonoDroid:    at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_(IntPtr , IntPtr , IntPtr ) in Mono.Android.dll:token 0x60000e6+0x12
07-09 10:07:07.076  3682  3682 I MonoDroid:     at com.xamarin.subscribetoappdomainunhandledexception.MainActivity.n_onCreate(Native Method)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at com.xamarin.subscribetoappdomainunhandledexception.MainActivity.onCreate(MainActivity.java:29)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.Activity.performCreate(Activity.java:7994)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.Activity.performCreate(Activity.java:7978)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3404)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.os.Handler.dispatchMessage(Handler.java:106)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.os.Looper.loop(Looper.java:223)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at android.app.ActivityThread.main(ActivityThread.java:7664)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at java.lang.reflect.Method.invoke(Native Method)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
07-09 10:07:07.076  3682  3682 I MonoDroid:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

@BrzVlad BrzVlad self-assigned this Jul 14, 2021
@ghost ghost added in-pr There is an active PR which will close this issue when it is merged and removed in-pr There is an active PR which will close this issue when it is merged labels Jul 19, 2021
@steveisok
Copy link
Member

The Android team was able to find another way via dotnet/android@c1a2ee7

Closing

jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Jul 23, 2021
Context: c1a2ee7
Context: dotnet/runtime#44526

If c1a2ee7 is working now, we should be able to enable this test.
@grendello
Copy link
Contributor

The Android team was able to find another way via xamarin/xamarin-android@c1a2ee7

Closing

@steveisok The above commit deals with propagation to managed code of exceptions thrown in Java code, it doesn't make the test mentioned by @jonathanpeppers work. I've just tested it, we still don't see AppDomain.UnhandledException raised.
This is because the test throws a managed exception from Activity.OnCreate and not from a Java code, thus the codepath in UnhandledException which calls mono_unhandled_exception is never hit.

@jonpryor
Copy link
Member

jonpryor commented Jul 26, 2021

@grendello wrote:

This is because the test throws a managed exception from Activity.OnCreate() and not from a Java code

This doesn't entirely make sense to me: if there is no debugger attached, then the managed exception should be captured at the JNI boundary, re-raised in Java, and thus should eventually hit mono_unhandled_exception().

If a debugger is attached, then we're in the world of mono_debugger_agent_unhandled_exception() and commit dotnet/android@e4debf7, and after the debugger is notified of the pending exception, all bets are off, as mono will then deal with stack unwinding, which will implicitly corrupt JVM state.

Does the SubscribeToAppDomainUnhandledException() test run with the debugger attached or without the debugger attached? It doesn't look like the debugger is attached: https://github.com/xamarin/xamarin-android/blob/2ead7f439dd58b866af3a62ebb8f6f9a9ae9a5c0/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs#L64-L91

@grendello
Copy link
Contributor

@grendello wrote:

This is because the test throws a managed exception from Activity.OnCreate() and not from a Java code

This doesn't entirely make sense to me: if there is no debugger attached, then the managed exception should be captured at the JNI boundary, re-raised in Java, and thus should eventually hit mono_unhandled_exception().

It never does, I checked that. What I think is happening is that Mono reports the unhandled exception before it gets to the Java side and aborts.

@grendello
Copy link
Contributor

The log from the test contains the following interesting bits:

07-26 10:50:54.619  6959  6959 W monodroid: MonodroidRuntime::monodroid_pinvoke_override ("java-interop", "java_interop_jnienv_throw")
07-26 10:50:54.619  6959  6959 I monodroid-timing: p/invoke cache lookup for 'java_interop_jnienv_throw' (internal); elapsed: 0s:0::729
07-26 10:50:54.619  6959  6959 I monodroid-timing: p/invoke override for 'java_interop_jnienv_throw' (internal); elapsed: 0s:0::886
07-26 10:50:54.619  6959  6959 W monodroid: Found java-interop@java_interop_jnienv_throw in internal p/invoke map (0x7b1b677594)
07-26 10:50:54.619  6959  6959 D AndroidRuntime: Shutting down VM
--------- beginning of crash
07-26 10:50:54.620  6959  6959 E AndroidRuntime: FATAL EXCEPTION: main
07-26 10:50:54.620  6959  6959 E AndroidRuntime: Process: com.xamarin.subscribetoappdomainunhandledexception, PID: 6959
07-26 10:50:54.620  6959  6959 E AndroidRuntime: android.runtime.JavaProxyThrowable: System.Exception: CRASH
07-26 10:50:54.620  6959  6959 E AndroidRuntime:    at UnnamedProject.MainActivity.OnCreate(Bundle bundle) in UnnamedProject.dll:token 0x6000001+0x70
07-26 10:50:54.620  6959  6959 E AndroidRuntime:    at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_(IntPtr , IntPtr , IntPtr ) in Mono.Android.dll:token 0x60000e6+0x12
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at com.xamarin.subscribetoappdomainunhandledexception.MainActivity.n_onCreate(Native Method)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at com.xamarin.subscribetoappdomainunhandledexception.MainActivity.onCreate(MainActivity.java:29)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.app.Activity.performCreate(Activity.java:8036)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.app.Activity.performCreate(Activity.java:8016)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3581)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3765)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:102)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2193)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:106)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.os.Looper.loopOnce(Looper.java:201)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:288)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:7796)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-26 10:50:54.620  6959  6959 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:974)
07-26 10:50:54.621  6959  6959 E andledexceptio: * Assertion: should not be reached at /__w/1/s/src/mono/mono/component/debugger-stub.c:175
07-26 10:50:54.621  6959  6959 F libc    : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 6959 (andledexception), pid 6959 (andledexception)
07-26 10:50:54.656  6987  6987 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstoneProto
07-26 10:50:54.657   882   882 I tombstoned: received crash request for pid 6959
07-26 10:50:54.657  6987  6987 I crash_dump64: performing dump of process 6959 (target tid = 6959)
07-26 10:50:54.685  6987  6987 E DEBUG   : failed to read /proc/uptime: Permission denied
07-26 10:50:54.843  6987  6987 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
07-26 10:50:54.843  6987  6987 F DEBUG   : Build fingerprint: 'google/crosshatch/crosshatch:S/SPB2.210513.011/7465093:user/release-keys'
07-26 10:50:54.843  6987  6987 F DEBUG   : Revision: 'MP1.0'
07-26 10:50:54.843  6987  6987 F DEBUG   : ABI: 'arm64'
07-26 10:50:54.843  6987  6987 F DEBUG   : Timestamp: 2021-07-26 10:50:54.684519069+0200
07-26 10:50:54.843  6987  6987 F DEBUG   : Process uptime: 0s
07-26 10:50:54.843  6987  6987 F DEBUG   : Cmdline: com.xamarin.subscribetoappdomainunhandledexception
07-26 10:50:54.843  6987  6987 F DEBUG   : pid: 6959, tid: 6959, name: andledexception  >>> com.xamarin.subscribetoappdomainunhandledexception <<<
07-26 10:50:54.843  6987  6987 F DEBUG   : uid: 10424
07-26 10:50:54.843  6987  6987 F DEBUG   : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
07-26 10:50:54.843  6987  6987 F DEBUG   :     x0  0000000000000000  x1  0000000000001b2f  x2  0000000000000006  x3  0000007fd2ff4e80
07-26 10:50:54.843  6987  6987 F DEBUG   :     x4  67626064711f6461  x5  67626064711f6461  x6  67626064711f6461  x7  7f7f7f7f7f7f7f7f
07-26 10:50:54.843  6987  6987 F DEBUG   :     x8  00000000000000f0  x9  77863297e2a4b1dd  x10 0000000000000000  x11 ffffff80fffffbdf
07-26 10:50:54.843  6987  6987 F DEBUG   :     x12 0000000000000001  x13 000000000000005c  x14 0000007fd2ff3d20  x15 0024f5968bf70b9d
07-26 10:50:54.843  6987  6987 F DEBUG   :     x16 0000007e3a8d9058  x17 0000007e3a8b5ec0  x18 0000007e44282000  x19 0000000000001b2f
07-26 10:50:54.843  6987  6987 F DEBUG   :     x20 0000000000001b2f  x21 00000000ffffffff  x22 0000007fd2ff59d0  x23 0000007d17fee598
07-26 10:50:54.843  6987  6987 F DEBUG   :     x24 0000000000000001  x25 0000007cf7f27650  x26 0000007b14c24570  x27 0000007e43f74000
07-26 10:50:54.843  6987  6987 F DEBUG   :     x28 0000007b18fcc000  x29 0000007fd2ff4f00
07-26 10:50:54.843  6987  6987 F DEBUG   :     lr  0000007e3a868b7c  sp  0000007fd2ff4e60  pc  0000007e3a868ba8  pst 0000000000000000
07-26 10:50:54.843  6987  6987 F DEBUG   : backtrace:
07-26 10:50:54.843  6987  6987 F DEBUG   :       #00 pc 000000000004fba8  /apex/com.android.runtime/lib64/bionic/libc.so (abort+164) (BuildId: 8955af85d8857f3d34c01c417042bb85)
07-26 10:50:54.843  6987  6987 F DEBUG   :       #01 pc 0000000000020504  /data/app/~~c-ggUtCWNYgYvcENZamU6g==/com.xamarin.subscribetoappdomainunhandledexception-_Rt5cYrDD4ysDtN2pR1mEQ==/lib/arm64/libmonodroid.so (xamarin::android::internal::MonodroidRuntime::mono_log_handler(char const*, char const*, char const*, int, void*)+144) (BuildId: 034d1a5f7c266ad241e244e00e402adafa185f1c)
07-26 10:50:54.843  6987  6987 F DEBUG   :       #02 pc 0000000000263018  /data/app/~~c-ggUtCWNYgYvcENZamU6g==/com.xamarin.subscribetoappdomainunhandledexception-_Rt5cYrDD4ysDtN2pR1mEQ==/lib/arm64/libmonosgen-2.0.so (BuildId: 5c5460bcdb75710c13015eaa06c9ea7c5cc65097)
07-26 10:50:54.843  6987  6987 F DEBUG   :       #03 pc 0000000000263144  /data/app/~~c-ggUtCWNYgYvcENZamU6g==/com.xamarin.subscribetoappdomainunhandledexception-_Rt5cYrDD4ysDtN2pR1mEQ==/lib/arm64/libmonosgen-2.0.so (BuildId: 5c5460bcdb75710c13015eaa06c9ea7c5cc65097)
07-26 10:50:54.843  6987  6987 F DEBUG   :       #04 pc 00000000002631a4  /data/app/~~c-ggUtCWNYgYvcENZamU6g==/com.xamarin.subscribetoappdomainunhandledexception-_Rt5cYrDD4ysDtN2pR1mEQ==/lib/arm64/libmonosgen-2.0.so (BuildId: 5c5460bcdb75710c13015eaa06c9ea7c5cc65097)
07-26 10:50:54.843  6987  6987 F DEBUG   :       #05 pc 000000000026c088  /data/app/~~c-ggUtCWNYgYvcENZamU6g==/com.xamarin.subscribetoappdomainunhandledexception-_Rt5cYrDD4ysDtN2pR1mEQ==/lib/arm64/libmonosgen-2.0.so (BuildId: 5c5460bcdb75710c13015eaa06c9ea7c5cc65097)
07-26 10:50:54.843  6987  6987 F DEBUG   :       #06 pc 000000000025e04c  /data/app/~~c-ggUtCWNYgYvcENZamU6g==/com.xamarin.subscribetoappdomainunhandledexception-_Rt5cYrDD4ysDtN2pR1mEQ==/lib/arm64/libmonosgen-2.0.so (mono_debugger_agent_unhandled_exception+60) (BuildId: 5c5460bcdb75710c13015eaa06c9ea7c5cc65097)
07-26 10:50:54.843  6987  6987 F DEBUG   :       #07 pc 0000000000008d88  <anonymous:7e37002000>

The assertion and the following backtrace are seen just after the Java runtime reports an unhandled exception thrown from managed code. However, before the exception propagation path kicks in, Mono aborts in mono_debugger_agent_unhandled_exception which ends up in the debugger component stub:

static void
stub_debugger_unhandled_exception (MonoException *exc)
{
        g_assert_not_reached ();
}

The test doesn't use the debugger (the project it generates is built in the Release configuration, so I mono_debugger_agent_unhandled_exception should probably never be called in this situation.

jonpryor added a commit to jonathanpeppers/xamarin-android that referenced this issue Jul 26, 2021
Context: dotnet/runtime#44526 (comment)
Context: dotnet/runtime#44526 (comment)
Context: start: https://discord.com/channels/732297728826277939/732297837953679412/869330822262587392
Context:   end? https://discord.com/channels/732297728826277939/732297837953679412/869343082552893440

On .NET 6, `JNIEnv.mono_unhandled_exception` is
`monodroid_debugger_unhandled_exception()`, which calls
`mono_debugger_agent_unhandled_exception()`; see also e4debf7.

The problem is that in our current world order of "Mono components"
(0f7a0cd), if the debugger isn't used, then we get "debugger stubs"
for the mono debugger agent, which turns
`mono_debugger_agent_unhandled_exception()` into an [*assertion*][0]:

	static void
	stub_debugger_unhandled_exception (MonoException *exc)
	{
		g_assert_not_reached ();
	}

The result is that when an exception is thrown, *before* the
`AppDomain.UnhandledException` event can be raised, the runtime dies
in a horrible flaming assertion death:

	E andledexceptio: * Assertion: should not be reached at /__w/1/s/src/mono/mono/component/debugger-stub.c:175

Avoid this issue by checking `Debugger.IsAttached` *before* calling
`monodroid_debugger_unhandled_exception()`.

Additionally, remove some obsolete comments: .NET 6 couldn't resolve
`Debugger.Mono_UnhandledException()` because .NET 6 never had it, so
the linker was right to warn about its absence.

[0]: https://github.com/dotnet/runtime/blob/16b456426dfb5212a24bfb78bfd5d9adfcc95185/src/mono/mono/component/debugger-stub.c#L172-L176
@grendello
Copy link
Contributor

With @jonpryor's change we now see the native mono_unhandled_exception function called via the monodroid_unhandled_exception icall (I modified our sources to print the icall function name on entry):

07-27 09:34:16.297 16947 16947 W monodroid: static void xamarin::android::internal::MonodroidRuntime::monodroid_unhandled_exception(MonoObject *)
07-27 09:34:16.303 16947 16947 E andledexceptio: (null) Cannot transition thread 0x7e452274f8 from STATE_BLOCKING with DO_BLOCKING
07-27 09:34:16.305 16947 16947 F libc    : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 16947 (andledexception), pid 16947 (andledexception)
07-27 09:34:16.347 16975 16975 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstoneProto
07-27 09:34:16.348   882   882 I tombstoned: received crash request for pid 16947
07-27 09:34:16.348 16975 16975 I crash_dump64: performing dump of process 16947 (target tid = 16947)
07-27 09:34:16.363 16210 16353 I tflite  : Initialized TensorFlow Lite runtime.
07-27 09:34:16.375 16975 16975 E DEBUG   : failed to read /proc/uptime: Permission denied
07-27 09:34:16.847 16975 16975 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
07-27 09:34:16.847 16975 16975 F DEBUG   : Build fingerprint: 'google/crosshatch/crosshatch:S/SPB2.210513.011/7465093:user/release-keys'
07-27 09:34:16.847 16975 16975 F DEBUG   : Revision: 'MP1.0'
07-27 09:34:16.847 16975 16975 F DEBUG   : ABI: 'arm64'
07-27 09:34:16.847 16975 16975 F DEBUG   : Timestamp: 2021-07-27 09:34:16.375092804+0200
07-27 09:34:16.847 16975 16975 F DEBUG   : Process uptime: 0s
07-27 09:34:16.847 16975 16975 F DEBUG   : Cmdline: com.xamarin.subscribetoappdomainunhandledexception
07-27 09:34:16.847 16975 16975 F DEBUG   : pid: 16947, tid: 16947, name: andledexception  >>> com.xamarin.subscribetoappdomainunhandledexception <<<
07-27 09:34:16.847 16975 16975 F DEBUG   : uid: 10426
07-27 09:34:16.847 16975 16975 F DEBUG   : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
07-27 09:34:16.847 16975 16975 F DEBUG   :     x0  0000000000000000  x1  0000000000004233  x2  0000000000000006  x3  0000007fd2ff47e0
07-27 09:34:16.847 16975 16975 F DEBUG   :     x4  1f6360647167731f  x5  1f6360647167731f  x6  1f6360647167731f  x7  7f7f7f7f7f7f7f7f
07-27 09:34:16.847 16975 16975 F DEBUG   :     x8  00000000000000f0  x9  77863297e2a4b1dd  x10 0000000000000000  x11 ffffff80fffffbdf
07-27 09:34:16.847 16975 16975 F DEBUG   :     x12 0000000000000001  x13 0000000000000052  x14 0000007c07f315b0  x15 0011f094d3a0f58d
07-27 09:34:16.847 16975 16975 F DEBUG   :     x16 0000007e3a8d9058  x17 0000007e3a8b5ec0  x18 0000007e44282000  x19 0000000000004233
07-27 09:34:16.847 16975 16975 F DEBUG   :     x20 0000000000004233  x21 00000000ffffffff  x22 0000007b19b0f000  x23 0000007b19b1f798
07-27 09:34:16.847 16975 16975 F DEBUG   :     x24 0000007c07f2fdb8  x25 0000007cb7f22010  x26 0000007c97fc0970  x27 0000007d17feaea0
07-27 09:34:16.847 16975 16975 F DEBUG   :     x28 0000007cd7f24870  x29 0000007fd2ff4860
07-27 09:34:16.847 16975 16975 F DEBUG   :     lr  0000007e3a868b7c  sp  0000007fd2ff47c0  pc  0000007e3a868ba8  pst 0000000000000000
07-27 09:34:16.847 16975 16975 F DEBUG   : backtrace:
07-27 09:34:16.847 16975 16975 F DEBUG   :       #00 pc 000000000004fba8  /apex/com.android.runtime/lib64/bionic/libc.so (abort+164) (BuildId: 8955af85d8857f3d34c01c417042bb85)
07-27 09:34:16.847 16975 16975 F DEBUG   :       #01 pc 00000000000202a0  /data/app/~~WGzlJqoXcJAxg3MqgIETrw==/com.xamarin.subscribetoappdomainunhandledexception-MS3ExbrN3P6rmyqfwgfA_g==/lib/arm64/libmonodroid.so (xamarin::android::internal::MonodroidRuntime::mono_log_handler(char const*, char const*, char const*, int, void*)+144) (BuildId: a51175cc7642482edf081242e71d8c3c8068e255)
07-27 09:34:16.847 16975 16975 F DEBUG   :       #02 pc 0000000000263018  /data/app/~~WGzlJqoXcJAxg3MqgIETrw==/com.xamarin.subscribetoappdomainunhandledexception-MS3ExbrN3P6rmyqfwgfA_g==/lib/arm64/libmonosgen-2.0.so (BuildId: a4973039d62bfbd82ebd74464acfa3feac913079)
07-27 09:34:16.847 16975 16975 F DEBUG   :       #03 pc 00000000002630a0  /data/app/~~WGzlJqoXcJAxg3MqgIETrw==/com.xamarin.subscribetoappdomainunhandledexception-MS3ExbrN3P6rmyqfwgfA_g==/lib/arm64/libmonosgen-2.0.so (BuildId: a4973039d62bfbd82ebd74464acfa3feac913079)
07-27 09:34:16.847 16975 16975 F DEBUG   :       #04 pc 000000000010aaac  /data/app/~~WGzlJqoXcJAxg3MqgIETrw==/com.xamarin.subscribetoappdomainunhandledexception-MS3ExbrN3P6rmyqfwgfA_g==/lib/arm64/libmonosgen-2.0.so (BuildId: a4973039d62bfbd82ebd74464acfa3feac913079)
07-27 09:34:16.847 16975 16975 F DEBUG   :       #05 pc 000000000010c324  /data/app/~~WGzlJqoXcJAxg3MqgIETrw==/com.xamarin.subscribetoappdomainunhandledexception-MS3ExbrN3P6rmyqfwgfA_g==/lib/arm64/libmonosgen-2.0.so (BuildId: a4973039d62bfbd82ebd74464acfa3feac913079)
07-27 09:34:16.847 16975 16975 F DEBUG   :       #06 pc 0000000000097a00  /data/app/~~WGzlJqoXcJAxg3MqgIETrw==/com.xamarin.subscribetoappdomainunhandledexception-MS3ExbrN3P6rmyqfwgfA_g==/lib/arm64/libmonosgen-2.0.so (BuildId: a4973039d62bfbd82ebd74464acfa3feac913079)
07-27 09:34:16.847 16975 16975 F DEBUG   :       #07 pc 00000000001a45dc  /data/app/~~WGzlJqoXcJAxg3MqgIETrw==/com.xamarin.subscribetoappdomainunhandledexception-MS3ExbrN3P6rmyqfwgfA_g==/lib/arm64/libmonosgen-2.0.so (BuildId: a4973039d62bfbd82ebd74464acfa3feac913079)
07-27 09:34:16.847 16975 16975 F DEBUG   :       #08 pc 0000000000008c50  <anonymous:7e3c781000>

After that the runtime calls abort() and the process is terminated, however we still don't appear to see the AppDomain.UnhandledException event. This line looks suspicious:

07-27 09:34:16.303 16947 16947 E andledexceptio: (null) Cannot transition thread 0x7e452274f8 from STATE_BLOCKING with DO_BLOCKING

The fatal error is reported by Mono, perhaps that's what eventually prevents the event from being raised? Perhaps the runtime is aborted before it even gets to the stage where it would raise the event?

@thaystg
Copy link
Member

thaystg commented Jul 27, 2021

I'll try to fix it: Cannot transition thread 0x7e452274f8 from STATE_BLOCKING with DO_BLOCKING

@thaystg
Copy link
Member

thaystg commented Jul 27, 2021

Fixed #56380
I could test and check that the correct message is being printed on adb logcat.

jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Jul 31, 2021
Context: c1a2ee7
Context: dotnet/runtime#44526

If c1a2ee7 is working now, we should be able to enable this test.
jonathanpeppers pushed a commit to jonathanpeppers/xamarin-android that referenced this issue Jul 31, 2021
Context: dotnet/runtime#44526 (comment)
Context: dotnet/runtime#44526 (comment)
Context: start: https://discord.com/channels/732297728826277939/732297837953679412/869330822262587392
Context:   end? https://discord.com/channels/732297728826277939/732297837953679412/869343082552893440

On .NET 6, `JNIEnv.mono_unhandled_exception` is
`monodroid_debugger_unhandled_exception()`, which calls
`mono_debugger_agent_unhandled_exception()`; see also e4debf7.

The problem is that in our current world order of "Mono components"
(0f7a0cd), if the debugger isn't used, then we get "debugger stubs"
for the mono debugger agent, which turns
`mono_debugger_agent_unhandled_exception()` into an [*assertion*][0]:

	static void
	stub_debugger_unhandled_exception (MonoException *exc)
	{
		g_assert_not_reached ();
	}

The result is that when an exception is thrown, *before* the
`AppDomain.UnhandledException` event can be raised, the runtime dies
in a horrible flaming assertion death:

	E andledexceptio: * Assertion: should not be reached at /__w/1/s/src/mono/mono/component/debugger-stub.c:175

Avoid this issue by checking `Debugger.IsAttached` *before* calling
`monodroid_debugger_unhandled_exception()`.

Additionally, remove some obsolete comments: .NET 6 couldn't resolve
`Debugger.Mono_UnhandledException()` because .NET 6 never had it, so
the linker was right to warn about its absence.

[0]: https://github.com/dotnet/runtime/blob/16b456426dfb5212a24bfb78bfd5d9adfcc95185/src/mono/mono/component/debugger-stub.c#L172-L176
jonpryor pushed a commit to dotnet/android that referenced this issue Aug 12, 2021
Context: c1a2ee7
Context: dotnet/runtime#44526
Context: dotnet/runtime#44526 (comment)
Context: dotnet/runtime#44526 (comment)
Context: start: https://discord.com/channels/732297728826277939/732297837953679412/869330822262587392
Context:   end? https://discord.com/channels/732297728826277939/732297837953679412/869343082552893440
Context: dotnet/runtime#57304

Now that we are calling `mono_unhandled_exception()` when an unhandled
exception is reported (c1a2ee7), we should be able re-enable the
`InstallAndRunTests.SubscribeToAppDomainUnhandledException()` unit
test on .NET 6, which was disabled in 6e3e383.

What seemed like it should have been a 1-line removal ballooned a bit
due to a confluence of factors:

 1. Debugger component stubs, and
 2. .NET 6 `Console.WriteLine()` behavior.

On .NET 6, `JNIEnv.mono_unhandled_exception()` is
`monodroid_debugger_unhandled_exception()`, which calls
`mono_debugger_agent_unhandled_exception()`; see also e4debf7.

The problem is that in our current world order of "Mono components"
(0f7a0cd), if the debugger isn't used, then we get "debugger stubs"
for the mono debugger agent, which turns
`mono_debugger_agent_unhandled_exception()` into an [*assertion*][0]:

	static void
	stub_debugger_unhandled_exception (MonoException *exc)
	{
		g_assert_not_reached ();
	}

The result is that when an exception is thrown, *before* the
`AppDomain.UnhandledException` event can be raised, the runtime dies
in a horrible flaming assertion death:

	E andledexceptio: * Assertion: should not be reached at /__w/1/s/src/mono/mono/component/debugger-stub.c:175

Avoid this issue by checking `Debugger.IsAttached` *before* calling
`monodroid_debugger_unhandled_exception()`.

Additionally, remove some obsolete comments: .NET 6 couldn't resolve
`Debugger.Mono_UnhandledException()` because .NET 6 never had it, so
the linker was right to warn about its absence.

The problem with .NET 6 & `Console.WriteLine()` is that when format
strings are used, the output may be line-wrapped in unexpected ways;
see also dotnet/runtime@#57304.  Additionally, the `sender` parameter
value differs under .NET 6.  These two issues broke our unit test;
we *expected* `adb logcat` to contain:

	# Unhandled Exception: sender=RootDomain; e.IsTerminating=True; e.ExceptionObject=System.Exception: CRASH

Under .NET 6, `adb logcat` *instead* contained:

	# Unhandled Exception: sender=System.Object; e.IsTerminating=True; e.ExceptionObject=System.Exception
	: CRASH

Yes, `: CRASH` was on a separate `adb logcat` line.

Fix the `SubscribeToAppDomainUnhandledException()` unit test so that
`adb logcat` messages can now span multiple lines (which is sure to
cause all sorts of GC garbage!), and update the expected message so
that we look for the right message under legacy & .NET 6.

Co-authored-by: Jonathan Pryor <jonpryor@vt.edu>

[0]: https://github.com/dotnet/runtime/blob/16b456426dfb5212a24bfb78bfd5d9adfcc95185/src/mono/mono/component/debugger-stub.c#L172-L176
@ghost ghost locked as resolved and limited conversation to collaborators Aug 27, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants