-
Notifications
You must be signed in to change notification settings - Fork 538
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
Can't handle exception by AppDomain.UnhandledException
when thrown in Executor
thread
#6211
Comments
grendello
added a commit
to grendello/xamarin-android
that referenced
this issue
Aug 23, 2021
Fixes: dotnet#6211 Mono VM will return a valid AppDomain pointer (both in "legacy" and NET6 cases) only if the current thread is attached to some domain. It is possible that when managed code is called from an unattached Java thread, `mono_domain_get()` will return a `NULL` pointer instead of a valid one. If we pass this pointer along to Mono, a segfault may occur if Mono fails to validate the passed pointer. Sample code which may trigger the problem: ```csharp public override void OnCreate() { AppDomain.CurrentDomain.UnhandledException += (sender, e) => { Console.WriteLine("!!! UnhandledException: " + e.ExceptionObject.GetType().FullName); }; base.OnCreate(); } protected override void OnStart() { base.OnStart(); Java.Util.Concurrent.Executors.NewSingleThreadExecutor() .Execute(new Runnable(() => { throw new Exception("Exception from Java Executor!"); })); } ``` Possible crashes caused by the above code: 08-20 15:00:20.619 19214 19241 F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xb8 in tid 19241 (pool-1-thread-1), pid 19214 (ndroidcrashtest) 08-20 15:00:20.786 19245 19245 F DEBUG : backtrace: 08-20 15:00:20.786 1648 1648 I hwservicemanager: getTransport: Cannot find entry [email protected]::IMapper/default in either framework or device manifest. 08-20 15:00:20.786 19245 19245 F DEBUG : #00 pc 0011b72f /apex/com.android.runtime/lib/bionic/libc.so (pthread_mutex_lock+31) (BuildId: 471745f0fbbcedb3db1553d5bd6fcd8b) 08-20 15:00:20.786 19245 19245 F DEBUG : #1 pc 0015240d /data/app/com.companyname.androidcrashtest-sqgk-Mnu8GZM5hKPu1yWEQ==/lib/x86/libmonosgen-2.0.so (mono_domain_assembly_search+61) 08-20 15:22:04.462 19737 19763 F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xb8 in tid 19763 (pool-1-thread-1), pid 19737 (ndroidcrashtest) 08-20 15:22:04.599 19767 19767 F DEBUG : backtrace: 08-20 15:22:04.599 19767 19767 F DEBUG : #00 pc 0011b72f /apex/com.android.runtime/lib/bionic/libc.so (pthread_mutex_lock+31) (BuildId: 471745f0fbbcedb3db1553d5bd6fcd8b) 08-20 15:22:04.599 19767 19767 F DEBUG : #1 pc 0026b91a /data/app/com.companyname.androidcrashtest-JQoYc3YFwZtEoSJlTqX_BA==/lib/x86/libmonosgen-2.0.so (mono_os_mutex_lock+42) To avoid the above situation, wrap the `mono_domain_get()` call in a method which checks the return value and, if it's `nullptr`, it calls `mono_get_root_domain()` and attaches the current thread to that domain.
jonpryor
pushed a commit
that referenced
this issue
Aug 26, 2021
Fixes: #6211 Mono VM will return a valid AppDomain pointer (both in "legacy" and NET6 cases) only if the current thread is attached to some domain. It is possible that when managed code is called from an unattached Java thread, `mono_domain_get()` will return `nullptr` instead of a valid one. If we further pass `nullptr` to other Mono functions, a segfault may occur if Mono fails to validate the passed pointer. Sample code which may trigger the problem: public override void OnCreate() { AppDomain.CurrentDomain.UnhandledException += (sender, e) => { Console.WriteLine("!!! UnhandledException: " + e.ExceptionObject.GetType().FullName); }; base.OnCreate(); } protected override void OnStart() { base.OnStart(); Java.Util.Concurrent.Executors.NewSingleThreadExecutor() .Execute(new Runnable(() => { throw new Exception("Exception from Java Executor!"); })); } Possible crash caused by the above code: F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xb8 in tid 19241 (pool-1-thread-1), pid 19214 (ndroidcrashtest) F DEBUG : backtrace: I hwservicemanager: getTransport: Cannot find entry [email protected]::IMapper/default in either framework or device manifest. F DEBUG : #00 pc 0011b72f /apex/com.android.runtime/lib/bionic/libc.so (pthread_mutex_lock+31) (BuildId: 471745f0fbbcedb3db1553d5bd6fcd8b) F DEBUG : #1 pc 0015240d /data/app/com.companyname.androidcrashtest-sqgk-Mnu8GZM5hKPu1yWEQ==/lib/x86/libmonosgen-2.0.so (mono_domain_assembly_search+61) F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xb8 in tid 19763 (pool-1-thread-1), pid 19737 (ndroidcrashtest) F DEBUG : backtrace: F DEBUG : #00 pc 0011b72f /apex/com.android.runtime/lib/bionic/libc.so (pthread_mutex_lock+31) (BuildId: 471745f0fbbcedb3db1553d5bd6fcd8b) F DEBUG : #1 pc 0026b91a /data/app/com.companyname.androidcrashtest-JQoYc3YFwZtEoSJlTqX_BA==/lib/x86/libmonosgen-2.0.so (mono_os_mutex_lock+42) To avoid the above situation, wrap the `mono_domain_get()` call into `utils.get_current_domain()` which checks the return value of `mono_domain_get()` and, if it's `nullptr`, calls `mono_get_root_domain()` and attaches the current thread to that root domain.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Steps to Reproduce
Set a handler on
Application.OnCreate
.Throw an exception on a thread made by
Java.Util.Concurrent.Executors
. In this example, the program is written onMainActivity.OnStart
.Project file: AndroidCrashTest.zip
Expected Behavior
The message
!!! UnhandledException
is written on Logcat before crash.Actual Behavior
A crash occurs with SIGSEGV before the exception handler is called.
Version Information
Visual Studio 16.11.1 on Windows 10, Android Emulator (API 29, x86)
This issue can be reproduced when the project is built with both Debug and Release configuration. And also can be reproduced with the latest source code with some patches to build xamarin-android on my environment.
Log File
logcat
Investigation
Tombstone indicates the cause is null pointer dereference. I think
mono_domain_get
in this line returns null. https://github.com/xamarin/xamarin-android/blob/33f380858d2f7ca41f45856c552c80bca2ca0a67/src/monodroid/jni/monodroid-glue.cc#L2408To prove this hypothesis, I added log outputs around
domain
usages and ran the application. The log indicatesdomain
is null and the crash occurred in get_android_runtime_class.Full Log
The text was updated successfully, but these errors were encountered: