[mini] Enter GC Unsafe mode in handle_signal_exception (#88436)
authorAleksey Kliger (λgeek) <alklig@microsoft.com>
Tue, 18 Jul 2023 03:16:21 +0000 (23:16 -0400)
committerGitHub <noreply@github.com>
Tue, 18 Jul 2023 03:16:21 +0000 (23:16 -0400)
When the runtime needs to turn some kinds of signals into managed
exceptions (for example: SIGINT turns into
`new ExecutionEngineException ("Interrupted (SIGINT)")`, and some
SIGFPE turn into `DivideByZeroException`, and some SIGSEGV turn into a
`NullReferenceException`) instead of unwinding the stack from inside a
signal handler it instead adjusts the normal stack so that when the
signal handler returns, execution will resume in
`handle_signal_exception`.

That means that if the runtime was in GC Safe mode when the signal
was raised, even if the signal handler code transitions to GC Unsafe
mode, by the time the `handle_signal_exception` runs, we will have
undone the GC Unsafe transition and will be back in GC Safe.

That means if the code in `handle_signal_exception` (notably
`mono_handle_exception`) calls anything that tries to do a transition
to GC Safe, we may get an assertion.

Fixes https://github.com/dotnet/runtime/issues/88405

src/mono/mono/mini/exceptions-amd64.c
src/mono/mono/mini/exceptions-arm.c
src/mono/mono/mini/exceptions-arm64.c
src/mono/mono/mini/exceptions-ppc.c
src/mono/mono/mini/exceptions-riscv.c
src/mono/mono/mini/exceptions-s390x.c
src/mono/mono/mini/exceptions-x86.c

index 2b0ceb5..3db3785 100644 (file)
@@ -764,8 +764,12 @@ handle_signal_exception (gpointer obj)
 
        memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));
 
+       MONO_ENTER_GC_UNSAFE_UNBALANCED;
+
        mono_handle_exception (&ctx, (MonoObject *)obj);
 
+       MONO_EXIT_GC_UNSAFE_UNBALANCED;
+
        mono_restore_context (&ctx);
 }
 
index bd544ee..f4bd609 100644 (file)
@@ -574,8 +574,12 @@ handle_signal_exception (gpointer obj)
 
        memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));
 
+       MONO_ENTER_GC_UNSAFE_UNBALANCED;
+       
        mono_handle_exception (&ctx, (MonoObject*)obj);
 
+       MONO_EXIT_GC_UNSAFE_UNBALANCED;
+
        mono_restore_context (&ctx);
 }
 
index 40b026a..b558255 100644 (file)
@@ -522,8 +522,12 @@ handle_signal_exception (gpointer obj)
 
        memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));
 
+       MONO_ENTER_GC_UNSAFE_UNBALANCED;
+
        mono_handle_exception (&ctx, (MonoObject*)obj);
 
+       MONO_EXIT_GC_UNSAFE_UNBALANCED;
+
        mono_restore_context (&ctx);
 }
 
index 69f6c49..146fece 100644 (file)
@@ -734,8 +734,12 @@ handle_signal_exception (gpointer obj)
 
        memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));
 
+       MONO_ENTER_GC_UNSAFE_UNBALANCED;
+
        mono_handle_exception (&ctx, obj);
 
+       MONO_EXIT_GC_UNSAFE_UNBALANCED;
+
        mono_restore_context (&ctx);
 }
 
index 8ae90e7..830efef 100644 (file)
@@ -390,7 +390,12 @@ handle_signal_exception (gpointer obj)
        MonoJitTlsData *jit_tls = mono_tls_get_jit_tls ();
        MonoContext ctx = jit_tls->ex_ctx;
 
+       MONO_ENTER_GC_UNSAFE_UNBALANCED;
+
        mono_handle_exception (&ctx, obj);
+
+       MONO_EXIT_GC_UNSAFE_UNBALANCED;
+
        mono_restore_context (&ctx);
 }
 
index c13ede7..6c40214 100644 (file)
@@ -673,7 +673,13 @@ handle_signal_exception (gpointer obj)
        MonoContext ctx;
 
        memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));
+
+       MONO_ENTER_GC_UNSAFE_UNBALANCED;
+
        mono_handle_exception (&ctx, obj);
+
+       MONO_EXIT_GC_UNSAFE_UNBALANCED;
+
        mono_restore_context (&ctx);
 }
 
index e838fe7..c51181d 100644 (file)
@@ -935,8 +935,12 @@ handle_signal_exception (gpointer obj)
 
        memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));
 
+       MONO_ENTER_GC_UNSAFE_UNBALANCED;
+
        mono_handle_exception (&ctx, (MonoObject*)obj);
 
+       MONO_EXIT_GC_UNSAFE_UNBALANCED;
+
        mono_restore_context (&ctx);
 }