diff --git a/runtime/COOP.md b/runtime/COOP.md index a2501c4f00b1..086ef1fd67a6 100644 --- a/runtime/COOP.md +++ b/runtime/COOP.md @@ -120,3 +120,41 @@ Debugging tips * Display the current thread state: display (void *) mono_thread_info_current ()->thread_state + +Enable GC Assertions +==================== + +Apply this patch to the iOS SDK (here only done for the `arm64_32` runtime): +```patch +diff --git a/sdks/builds/ios.mk b/sdks/builds/ios.mk +index 571dbd797a8..5bbe30040d2 100644 +--- a/sdks/builds/ios.mk ++++ b/sdks/builds/ios.mk +@@ -155,7 +155,7 @@ watchos64_32_sysroot = -isysroot $(watchos64_32_sysroot_path) + # explicitly disable dtrace, since it requires inline assembly, which is disabled on AppleTV (and mono's configure.ac doesn't know that (yet at least)) + ios-targettv_CONFIGURE_FLAGS = --enable-dtrace=no --enable-llvm-runtime --with-bitcode=yes + ios-targetwatch_CONFIGURE_FLAGS = --enable-cooperative-suspend --enable-llvm-runtime --with-bitcode=yes +-ios-targetwatch64_32_CONFIGURE_FLAGS = --enable-cooperative-suspend --enable-llvm-runtime --with-bitcode=yes ++ios-targetwatch64_32_CONFIGURE_FLAGS = --enable-cooperative-suspend --enable-llvm-runtime --with-bitcode=yes --enable-checked-build=gc + + ios-target32_SYSROOT = $(ios_sysroot) -miphoneos-version-min=$(IOS_VERSION_MIN) + ios-target32s_SYSROOT = $(ios_sysroot) -miphoneos-version-min=$(IOS_VERSION_MIN) +``` + +and make sure you build `xamarin-macios` with `MONO_BUILD_FROM_SOURCE=1`. Also modify `mtouch` such that it enables checked-build: + +```patch +diff --git a/tools/mtouch/mtouch.cs b/tools/mtouch/mtouch.cs +index 1ef159b79..cb2caf426 100644 +--- a/tools/mtouch/mtouch.cs ++++ b/tools/mtouch/mtouch.cs +@@ -649,6 +654,8 @@ namespace Xamarin.Bundler + sw.WriteLine ("\tsetenv (\"MONO_GC_PARAMS\", \"{0}\", 1);", app.MonoGCParams); + foreach (var kvp in app.EnvironmentVariables) + sw.WriteLine ("\tsetenv (\"{0}\", \"{1}\", 1);", kvp.Key.Replace ("\"", "\\\""), kvp.Value.Replace ("\"", "\\\"")); ++ sw.WriteLine ("\tsetenv (\"MONO_CHECK_MODE\", \"gc\", 1);"); ++ + sw.WriteLine ("\txamarin_supports_dynamic_registration = {0};", app.DynamicRegistrationSupported ? "TRUE" : "FALSE"); + sw.WriteLine ("}"); + sw.WriteLine (); +``` diff --git a/runtime/runtime.m b/runtime/runtime.m index 19e9e74bfcaf..79cdc638aadf 100644 --- a/runtime/runtime.m +++ b/runtime/runtime.m @@ -512,7 +512,7 @@ -(void) xamarinSetGCHandle: (int) gc_handle; get_raw_gchandle_safe (id self) { // COOP: we call a selector, and that must only be done in SAFE mode. - MONO_ASSERT_GC_SAFE; + MONO_ASSERT_GC_SAFE_OR_DETACHED; id xself = self; return (int) [xself xamarinGetGCHandle]; } @@ -2361,8 +2361,10 @@ -(void) xamarinSetGCHandle: (int) gc_handle; exc_handle = [[ns_exception userInfo] objectForKey: @"XamarinManagedExceptionHandle"]; if (exc_handle != NULL) { int handle = [exc_handle getHandle]; + MONO_ENTER_GC_UNSAFE; MonoObject *exc = mono_gchandle_get_target (handle); mono_runtime_set_pending_exception ((MonoException *) exc, false); + MONO_EXIT_GC_UNSAFE; } else { int handle = xamarin_create_ns_exception (ns_exception, &exception_gchandle); if (exception_gchandle != 0) { diff --git a/runtime/trampolines.m b/runtime/trampolines.m index bdab794b5c5c..cc3ffc879570 100644 --- a/runtime/trampolines.m +++ b/runtime/trampolines.m @@ -613,7 +613,7 @@ xamarin_release_trampoline (id self, SEL sel) { // COOP: does not access managed memory: any mode, but it assumes safe mode upon entry (it takes locks, and doesn't switch to safe mode). - MONO_ASSERT_GC_SAFE; + MONO_ASSERT_GC_SAFE_OR_DETACHED; int ref_count; bool detach = false; @@ -676,7 +676,7 @@ xamarin_retain_trampoline (id self, SEL sel) { // COOP: safe mode upon entry, switches to unsafe when acccessing managed memory. - MONO_ASSERT_GC_SAFE; + MONO_ASSERT_GC_SAFE_OR_DETACHED; pthread_mutex_lock (&refcount_mutex); diff --git a/tools/common/StaticRegistrar.cs b/tools/common/StaticRegistrar.cs index c8aa9666e518..9591b211396a 100644 --- a/tools/common/StaticRegistrar.cs +++ b/tools/common/StaticRegistrar.cs @@ -3862,7 +3862,7 @@ void Specialize (AutoIndentStringBuilder sb, ObjCMethod method, List if (App.Embeddinator) body.WriteLine ("xamarin_embeddinator_initialize ();"); - body.WriteLine ("MONO_ASSERT_GC_SAFE;"); + body.WriteLine ("MONO_ASSERT_GC_SAFE_OR_DETACHED;"); body.WriteLine ("MONO_THREAD_ATTACH;"); // COOP: this will switch to GC_UNSAFE body.WriteLine ();