From f3b0f58ee49087f8ea6f3917a46dcd7872a173c9 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 5 Jul 2023 14:42:06 -0400 Subject: [PATCH] [mini] Enter GC Unsafe mode in handle_signal_exception 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 | 4 ++++ src/mono/mono/mini/exceptions-arm.c | 4 ++++ src/mono/mono/mini/exceptions-arm64.c | 4 ++++ src/mono/mono/mini/exceptions-ppc.c | 4 ++++ src/mono/mono/mini/exceptions-riscv.c | 5 +++++ src/mono/mono/mini/exceptions-s390x.c | 6 ++++++ src/mono/mono/mini/exceptions-x86.c | 4 ++++ 7 files changed, 31 insertions(+) diff --git a/src/mono/mono/mini/exceptions-amd64.c b/src/mono/mono/mini/exceptions-amd64.c index 2b0ceb5b0b589f..3db3785e9bfd18 100644 --- a/src/mono/mono/mini/exceptions-amd64.c +++ b/src/mono/mono/mini/exceptions-amd64.c @@ -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); } diff --git a/src/mono/mono/mini/exceptions-arm.c b/src/mono/mono/mini/exceptions-arm.c index bd544ee55ef228..f4bd6098eb4ec0 100644 --- a/src/mono/mono/mini/exceptions-arm.c +++ b/src/mono/mono/mini/exceptions-arm.c @@ -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); } diff --git a/src/mono/mono/mini/exceptions-arm64.c b/src/mono/mono/mini/exceptions-arm64.c index 40b026a4095333..b55825583cca8a 100644 --- a/src/mono/mono/mini/exceptions-arm64.c +++ b/src/mono/mono/mini/exceptions-arm64.c @@ -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); } diff --git a/src/mono/mono/mini/exceptions-ppc.c b/src/mono/mono/mini/exceptions-ppc.c index 69f6c490c13cb5..146fece236928e 100644 --- a/src/mono/mono/mini/exceptions-ppc.c +++ b/src/mono/mono/mini/exceptions-ppc.c @@ -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); } diff --git a/src/mono/mono/mini/exceptions-riscv.c b/src/mono/mono/mini/exceptions-riscv.c index 18b3f08798e1b2..04c55b4fe0ee0a 100644 --- a/src/mono/mono/mini/exceptions-riscv.c +++ b/src/mono/mono/mini/exceptions-riscv.c @@ -243,7 +243,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); } diff --git a/src/mono/mono/mini/exceptions-s390x.c b/src/mono/mono/mini/exceptions-s390x.c index c13ede7e922fdc..6c40214a13f742 100644 --- a/src/mono/mono/mini/exceptions-s390x.c +++ b/src/mono/mono/mini/exceptions-s390x.c @@ -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); } diff --git a/src/mono/mono/mini/exceptions-x86.c b/src/mono/mono/mini/exceptions-x86.c index e838fe7fc8d74d..c51181d9480366 100644 --- a/src/mono/mono/mini/exceptions-x86.c +++ b/src/mono/mono/mini/exceptions-x86.c @@ -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); }