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

[DotNet] Attach current thread to MonoVM when registering a type #7560

Merged
merged 20 commits into from
Nov 30, 2022

Conversation

grendello
Copy link
Contributor

@grendello grendello commented Nov 16, 2022

Fixes: #7532

Whenever any MonoVM APIs are called, the current thread of execution must be attached to the runtime or we risk native code crashes, for instance:

Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x40 in tid 1860 (jg_fr_pool_thre), pid 1792 (yname.sampleapp)
backtrace:
  00 pc 0011588e  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so
  01 pc 001156ae  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so
  02 pc 00115575  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so (mono_threads_enter_gc_unsafe_region_internal+53)
  03 pc 000973c3  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so (mono_runtime_invoke+51) (BuildId: c54662bbf82dbdadd595ca9d3e31dce29735885f)
  04 pc 00027ace  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonodroid.so (xamarin::android::internal::MonodroidRuntime::Java_mono_android_Runtime_register(_JNIEnv*, _jstring*, _jclass*, _jstring*)+286)
  05 pc 000279a0  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonodroid.so (Java_mono_android_Runtime_register+48)

The above trace translates to the following locations in the Mono runtime:

copy_stack_data_internal
/__w/1/s/src/mono/mono/utils/mono-threads-coop.c:191
copy_stack_data
/__w/1/s/src/mono/mono/utils/mono-threads-coop.c:246

mono_threads_enter_gc_unsafe_region_unbalanced_with_info
/__w/1/s/src/mono/mono/utils/mono-threads-coop.c:476

mono_runtime_invoke
/__w/1/s/src/mono/mono/metadata/object.c:2442

In this case, a pointer to Mono thread information structure (MonoThreadInfo*) is null in copy_stack_data which, in turn, causes the segfault when the pointer is dereferenced.

In the case of issue #7532, Java_mono_android_Runtime_register is called on behalf of a 3rd party library on a thread that is, most likely, created by that library and thus not (yet) attached to the runtime by the time the registration attempt is made.

Attach thread to the runtime by calling
mono_jit_thread_attach (nullptr) in DotNet builds to fix the issue. nullptr is used because .NET only has a single AppDomain and there's no need to pass around pointers to it.

Fixes: dotnet#7532

Whenever any MonoVM APIs are called, the current thread of execution
must be attached to the runtime or we risk native code crashes, for
instance:

    Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x40 in tid 1860 (jg_fr_pool_thre), pid 1792 (yname.sampleapp)
    backtrace:
      00 pc 0011588e  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so
      01 pc 001156ae  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so
      02 pc 00115575  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so (mono_threads_enter_gc_unsafe_region_internal+53)
      03 pc 000973c3  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so (mono_runtime_invoke+51) (BuildId: c54662bbf82dbdadd595ca9d3e31dce29735885f)
      04 pc 00027ace  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonodroid.so (xamarin::android::internal::MonodroidRuntime::Java_mono_android_Runtime_register(_JNIEnv*, _jstring*, _jclass*, _jstring*)+286)
      05 pc 000279a0  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonodroid.so (Java_mono_android_Runtime_register+48)

The above trace translates to the following locations in the Mono
runtime:

    copy_stack_data_internal
    /__w/1/s/src/mono/mono/utils/mono-threads-coop.c:191
    copy_stack_data
    /__w/1/s/src/mono/mono/utils/mono-threads-coop.c:246

    mono_threads_enter_gc_unsafe_region_unbalanced_with_info
    /__w/1/s/src/mono/mono/utils/mono-threads-coop.c:476

    mono_runtime_invoke
    /__w/1/s/src/mono/mono/metadata/object.c:2442

In this case, a pointer to Mono thread information
structure (`MonoThreadInfo*`) is null in `copy_stack_data` which, in
turn, causes the segfault when the pointer is dereferenced.

In the case of issue dotnet#7532, `Java_mono_android_Runtime_register` is
called on behalf of a 3rd party library on a thread that is, most
likely, created by that library and thus not (yet) attached to the
runtime by the time the registration attempt is made.

Attach thread to the runtime by calling
`mono_jit_thread_attach (nullptr)` in DotNet builds to fix the issue.
`nullptr` is used because .NET only has a single AppDomain and there's
no need to pass around pointers to it.
@jonpryor
Copy link
Member

Fixes: https://github.com/xamarin/xamarin-android/issues/7532

Whenever any MonoVM APIs are called, the current thread of execution
must be attached to the runtime or we risk native code crashes, e.g.:

	Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x40 in tid 1860 (jg_fr_pool_thre), pid 1792 (yname.sampleapp)
	backtrace:
	  00 pc 0011588e  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so
	  01 pc 001156ae  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so
	  02 pc 00115575  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so (mono_threads_enter_gc_unsafe_region_internal+53)
	  03 pc 000973c3  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so (mono_runtime_invoke+51) (BuildId: c54662bbf82dbdadd595ca9d3e31dce29735885f)
	  04 pc 00027ace  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonodroid.so (xamarin::android::internal::MonodroidRuntime::Java_mono_android_Runtime_register(_JNIEnv*, _jstring*, _jclass*, _jstring*)+286)
	  05 pc 000279a0  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonodroid.so (Java_mono_android_Runtime_register+48)

The above trace translates to the following locations in the Mono runtime:

	copy_stack_data_internal
	/__w/1/s/src/mono/mono/utils/mono-threads-coop.c:191
	copy_stack_data
	/__w/1/s/src/mono/mono/utils/mono-threads-coop.c:246

	mono_threads_enter_gc_unsafe_region_unbalanced_with_info
	/__w/1/s/src/mono/mono/utils/mono-threads-coop.c:476

	mono_runtime_invoke
	/__w/1/s/src/mono/mono/metadata/object.c:2442

In this case, a pointer to Mono thread information structure
(`MonoThreadInfo*`) is null in `copy_stack_data()` which, in turn,
causes the segfault when the pointer is dereferenced.

In the case of issue #7532, `Java_mono_android_Runtime_register()` is
called on behalf of a 3rd party library on a thread that is, most
likely, created by that library and thus not (yet) attached to the
runtime by the time the registration attempt is made.

Attach thread to the runtime by calling
`mono_jit_thread_attach(nullptr)` in .NET builds to fix the issue.
`nullptr` is used because .NET only has a single AppDomain and
there's no need to pass around pointers to it.

* main:
  [ci] Update PoliCheck exclusions (dotnet#7561)
  Bump to xamarin/xamarin-android-tools/main@59cac90 (dotnet#7546)
  Bump to dotnet/installer@355d664 8.0.100-alpha.1.22562.2 (dotnet#7505)
@grendello grendello added the do-not-merge PR should not be merged. label Nov 17, 2022
* main:
  Bump to xamarin/xamarin-android-tools/main@fa3711b (dotnet#7501)
* main:
  Bump to mono/mono@6dd9def5 (dotnet#7574)
  Bump to dotnet/installer@296eeb3 8.0.100-alpha.1.22570.9 (dotnet#7571)
  [ci] Add API-33 to the nightly build (dotnet#7552)
  [docs] Fix typo in XA0134 (dotnet#7569)
  [docs] how to `dotnet trace` our build (dotnet#7573)
  [Xamarin.Android.Build.Tasks] Useful errors when using binutils (dotnet#7566)
  Bump SQLite to 3.40.0 (dotnet#7564)
It won't fix the failure, but extra logging might be useful at some
point. The current failure is:

    droid.NET_Test: java_vm_ext.cc:570] JNI DETECTED ERROR IN APPLICATION: use of invalid jobject 0x7100941bb830
    backtrace:
           #00 pc 00000000000943f8  /apex/com.android.runtime/lib64/bionic/libc.so (syscall+24) (BuildId: a08a19770d6696739c847e29c3f5f650)
           #1 pc 0000000000097146  /apex/com.android.runtime/lib64/bionic/libc.so (abort+182) (BuildId: a08a19770d6696739c847e29c3f5f650)
           #2 pc 000000000055321f  /apex/com.android.runtime/lib64/libart.so (art::Runtime::Abort(char const*)+2399) (BuildId: 8bb3225e7c408f2ca23abac3db0417f2)
           #3 pc 000000000000c873  /system/lib64/libbase.so (android::base::LogMessage::~LogMessage()+611) (BuildId: 40d2b536dbf0730fdc31abd2b469f94f)
           dotnet#4 pc 00000000003ede64  /apex/com.android.runtime/lib64/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+1604) (BuildId: 8bb3225e7c408f2ca23abac3db0417f2)
           dotnet#5 pc 00000000003ee16a  /apex/com.android.runtime/lib64/libart.so (art::JavaVMExt::JniAbortF(char const*, char const*, ...)+234) (BuildId: 8bb3225e7c408f2ca23abac3db0417f2)
           dotnet#6 pc 00000000005adf7b  /apex/com.android.runtime/lib64/libart.so (art::Thread::DecodeJObject(_jobject*) const+875) (BuildId: 8bb3225e7c408f2ca23abac3db0417f2)
           dotnet#7 pc 00000000003def7b  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::ScopedCheck::CheckInstance(art::ScopedObjectAccess&, art::(anonymous namespace)::ScopedCheck::InstanceKind, _jobject*, bool)+91) (BuildId: 8bb3225e7c408f2ca23abac3db0417f2)
           dotnet#8 pc 00000000003de1e5  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::ScopedCheck::CheckPossibleHeapValue(art::ScopedObjectAccess&, char, art::(anonymous namespace)::JniValueType)+485) (BuildId: 8bb3225e7c408f2ca23abac3db0417f2)
           dotnet#9 pc 00000000003de2d4  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::ScopedCheck::CheckPossibleHeapValue(art::ScopedObjectAccess&, char, art::(anonymous namespace)::JniValueType)+724) (BuildId: 8bb3225e7c408f2ca23abac3db0417f2)
           dotnet#10 pc 00000000003dd712  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::ScopedCheck::Check(art::ScopedObjectAccess&, bool, char const*, art::(anonymous namespace)::JniValueType*)+690) (BuildId: 8bb3225e7c408f2ca23abac3db0417f2)
           dotnet#11 pc 00000000003e28c0  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::CheckJNI::CheckCallArgs(art::ScopedObjectAccess&, art::(anonymous namespace)::ScopedCheck&, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, art::InvokeType, art::(anonymous namespace)::VarArgs const*)+160) (BuildId: 8bb3225e7c408f2ca23abac3db0417f2)
           dotnet#12 pc 00000000003e1a9e  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::CheckJNI::CallMethodV(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, __va_list_tag*, art::Primitive::Type, art::InvokeType)+910) (BuildId: 8bb3225e7c408f2ca23abac3db0417f2)
           dotnet#13 pc 00000000003cf551  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::CheckJNI::CallObjectMethod(_JNIEnv*, _jobject*, _jmethodID*, ...)+177) (BuildId: 8bb3225e7c408f2ca23abac3db0417f2)
           dotnet#14 pc 00000000000013ec  /data/app/Mono.Android.NET_Tests--O9vgexkYeCx3nX-AuvLTQ==/split_config.x86_64.apk!libreuse-threads.so (offset 0xa8d000) (BuildId: 562d86d81ebdd3bb6b7528e2a9235ff84827294e)
           dotnet#15 pc 0000000000100fce  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+30) (BuildId: a08a19770d6696739c847e29c3f5f650)
           dotnet#16 pc 0000000000098fe7  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+55) (BuildId: a08a19770d6696739c847e29c3f5f650)
@jingliancui
Copy link

It look like the pipeline shown red, are there any plan date for preview version or release version? Because this 3rd party library is important in China region. Thanks.

* main:
  LEGO: Merge pull request 7584
  LEGO: Merge pull request 7582
  [build] Pass NuGet.config when restoring (dotnet#7578)
  Bump to xamarin/monodroid@8c54ea6d (dotnet#7576)
@grendello grendello removed the do-not-merge PR should not be merged. label Nov 28, 2022
@jonpryor jonpryor merged commit 73e16d5 into dotnet:main Nov 30, 2022
jonpryor pushed a commit that referenced this pull request Nov 30, 2022
…7560)

Fixes: #7532

Whenever any MonoVM APIs are called, the current thread of execution
must be attached to the runtime or we risk native code crashes, e.g.:

	Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x40 in tid 1860 (jg_fr_pool_thre), pid 1792 (yname.sampleapp)
	backtrace:
	  00 pc 0011588e  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so
	  01 pc 001156ae  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so
	  02 pc 00115575  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so (mono_threads_enter_gc_unsafe_region_internal+53)
	  03 pc 000973c3  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonosgen-2.0.so (mono_runtime_invoke+51) (BuildId: c54662bbf82dbdadd595ca9d3e31dce29735885f)
	  04 pc 00027ace  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonodroid.so (xamarin::android::internal::MonodroidRuntime::Java_mono_android_Runtime_register(_JNIEnv*, _jstring*, _jclass*, _jstring*)+286)
	  05 pc 000279a0  /data/app/~~lwgdvtQhIfK0II0Nd0mtag==/com.companyname.sampleapp-8yF54k9YuWCWpsuGRJvVQw==/lib/x86/libmonodroid.so (Java_mono_android_Runtime_register+48)

The above trace translates to the following locations in the Mono runtime:

	copy_stack_data_internal
	/__w/1/s/src/mono/mono/utils/mono-threads-coop.c:191
	copy_stack_data
	/__w/1/s/src/mono/mono/utils/mono-threads-coop.c:246

	mono_threads_enter_gc_unsafe_region_unbalanced_with_info
	/__w/1/s/src/mono/mono/utils/mono-threads-coop.c:476

	mono_runtime_invoke
	/__w/1/s/src/mono/mono/metadata/object.c:2442

In this case, a pointer to Mono thread information structure
(`MonoThreadInfo*`) is null in `copy_stack_data()` which, in turn,
causes the segfault when the pointer is dereferenced.

In the case of issue #7532, `Java_mono_android_Runtime_register()` is
called on behalf of a 3rd party library on a thread that is, most
likely, created by that library and thus not (yet) attached to the
runtime by the time the registration attempt is made.

Attach thread to the runtime by calling
`mono_jit_thread_attach(nullptr)` in .NET builds to fix the issue.
`nullptr` is used because .NET only has a single AppDomain and
there's no need to pass around pointers to it.

TODO: Try to create a test case.  Our attempted unit tests don't
cause an app crash when the fix isn't applied -- i.e. when
`mono_jit_thread_attach(nullptr)` *isn't* called -- which suggests
that we don't fully understand the reported bug report.
@grendello grendello deleted the issue7532 branch November 30, 2022 18:23
grendello added a commit to grendello/xamarin-android that referenced this pull request Nov 30, 2022
* main:
  Localized file check-in by OneLocBuild Task: Build definition ID 11410: Build ID 7029692 (dotnet#7575)
  [monodroid] Attach current thread to MonoVM when registering a type (dotnet#7560)
  [build] `make all` doesn't need `-m:1` (dotnet#7589)
  Update CODEOWNERS (dotnet#7593)
  [build] Add support for Visual Studio on win-arm64 (dotnet#7471)
  Fix reading assembly store hashes in AssemblyStoreReader
@github-actions github-actions bot locked and limited conversation to collaborators Jan 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3rd Party library internal invoke native code lead app crash
4 participants